DFS
286. 墙与门
题解:
class Solution {
private int[][] directions = new int[][] {
{-1, 0}, {1, 0}, {0, -1}, {0, 1}
};
public void wallsAndGates(int[][] rooms) {
final int m = rooms.length;
final int n = rooms[0].length;
for (int i = 0; i < m; i ++) {
for (int j = 0; j < n; j ++) {
if (Integer.MAX_VALUE == rooms[i][j]) {
bfs(rooms, i, j);
}
}
}
}
private void bfs(int[][] rooms, int x, int y) {
final int m = rooms.length;
final int n = rooms[0].length;
Queue<int[]> queue = new LinkedList<>();
boolean[][] visited = new boolean[m][n];
int step = 0;
queue.offer(new int[]{x, y});
while (!queue.isEmpty()) {
int size = queue.size();
step ++;
for (int i = 0; i < size; i ++) {
int[] curNode = queue.poll();
for (int d = 0; d < directions.length; d ++) {
int curX = curNode[0] + directions[d][0];
int curY = curNode[1] + directions[d][1];
if (curX < 0 || curX >= m || curY < 0 || curY >= n || visited[curX][curY] || (- 1 == rooms[curX][curY])) {
continue;
}
if (0 == rooms[curX][curY]) {
rooms[x][y] = step;
return ;
}
visited[curX][curY] = true;
queue.offer(new int[]{curX, curY});
}
}
}
}
}
200. 岛屿数量
题解:
class Solution {
private int[][] directions = new int[][]{
{-1, 0}, {0, -1}, {1, 0}, {0, 1}
};
public int numIslands(char[][] grid) {
final int m = grid.length;
final int n = grid[0].length;
int sum = 0;
for (int i = 0; i < m; i ++) {
for (int j = 0; j < n; j ++) {
if ('1' == grid[i][j]) {
sum ++;
grid[i][j] = '0';
bfs(grid, i, j);
}
}
}
return sum;
}
private void bfs(char[][] grid, int x, int y) {
final int m = grid.length;
final int n = grid[0].length;
boolean[][] visited = new boolean[m][n];
Queue<int[]> queue = new LinkedList<>();
queue.offer(new int[]{x, y});
visited[x][y] = true;
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i ++) {
int[] curNode = queue.poll();
for (int d = 0; d < directions.length; d ++) {
int curX = curNode[0] + directions[d][0];
int curY = curNode[1] + directions[d][1];
if (curX < 0 || curX >= m || curY < 0 || curY >= n || visited[curX][curY] || '0' == grid[curX][curY]) {
continue;
}
visited[curX][curY] = true;
grid[curX][curY] = '0';
queue.offer(new int[]{curX, curY});
}
}
}
}
}
279. 完全平方数
题解:
class Solution {
public int numSquares(int n) {
Queue<Integer> queue = new LinkedList<>();
queue.offer(n);
int step = 0;
while (!queue.isEmpty()) {
int size = queue.size();
step ++;
for (int i = 0; i < size; i ++) {
int curNode = queue.poll();
for (int j = (int)Math.sqrt(curNode); j > 0; j --) {
int temp = curNode - j * j;
if (temp < 0) {
continue;
}
if (0 == temp) {
return step;
}
queue.offer(temp);
}
}
}
return step;
}
}
133. 克隆图
总结:用hashMap做映射
题解:
/*
// Definition for a Node.
class Node {
public int val;
public List<Node> neighbors;
public Node() {
val = 0;
neighbors = new ArrayList<Node>();
}
public Node(int _val) {
val = _val;
neighbors = new ArrayList<Node>();
}
public Node(int _val, ArrayList<Node> _neighbors) {
val = _val;
neighbors = _neighbors;
}
}
*/
class Solution {
private HashMap <Node, Node> visited = new HashMap <> ();
public Node cloneGraph(Node node) {
if (node == null) {
return node;
}
// 如果该节点已经被访问过了,则直接从哈希表中取出对应的克隆节点返回
if (visited.containsKey(node)) {
return visited.get(node);
}
// 克隆节点,注意到为了深拷贝我们不会克隆它的邻居的列表
Node cloneNode = new Node(node.val, new ArrayList());
// 哈希表存储
visited.put(node, cloneNode);
// 遍历该节点的邻居并更新克隆节点的邻居列表
for (Node neighbor: node.neighbors) {
cloneNode.neighbors.add(cloneGraph(neighbor));
}
return cloneNode;
}
}
494. 目标和
题解:
class Solution {
private int sum = 0;
public int findTargetSumWays(int[] nums, int target) {
int total = 0;
dfs(nums, 0, target, total);
return sum;
}
private void dfs(int[] nums, int index, int target, int total) {
if (index > nums.length) {
return;
}
if (nums.length == index) {
if (total == target) {
sum ++;
}
return;
}
dfs(nums, index + 1, target, total + nums[index]);
dfs(nums, index + 1, target, total - nums[index]);
}
}
232. 用栈实现队列
题解:
class MyQueue {
private Stack<Integer> inStack;
private Stack<Integer> outStack;
private int size;
public MyQueue() {
inStack = new Stack<>();
outStack = new Stack<>();
size = 0;
}
public void push(int x) {
inStack.push(x);
size ++;
}
public int pop() {
if (!outStack.isEmpty()) {
size --;
return outStack.pop();
}
while (!inStack.isEmpty()) {
outStack.push(inStack.pop());
}
size --;
return outStack.pop();
}
public int peek() {
if (!outStack.isEmpty()) {
return outStack.peek();
}
while (!inStack.isEmpty()) {
outStack.push(inStack.pop());
}
return outStack.peek();
}
public boolean empty() {
return 0 == size;
}
}
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue obj = new MyQueue();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.peek();
* boolean param_4 = obj.empty();
*/
225. 用队列实现栈
题解:
class MyStack {
private Queue<Integer> data;
private Queue<Integer> helper;
private int size;
public MyStack() {
data = new LinkedList<>();
size = 0;
}
public void push(int x) {
size ++;
data.offer(x);
}
public int pop() {
helper = new LinkedList<>();
while (data.size() > 1) {
helper.offer(data.poll());
}
int temp = data.poll();
size --;
data = helper;
helper = null;
return temp;
}
public int top() {
helper = new LinkedList<>();
while (data.size() > 1) {
helper.offer(data.poll());
}
int temp = data.poll();
helper.offer(temp);
data = helper;
helper = null;
return temp;
}
public boolean empty() {
return 0 == size;
}
}
/**
* Your MyStack object will be instantiated and called as such:
* MyStack obj = new MyStack();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.top();
* boolean param_4 = obj.empty();
*/
542. 01 矩阵
题解:
// class Solution {
// private int[][] directions = new int[][]{
// {-1, 0}, {1, 0}, {0, 1}, {0, -1}
// };
// public int[][] updateMatrix(int[][] mat) {
// final int m = mat.length;
// final int n = mat[0].length;
// int[][] ans = new int[m][n];
// for (int i = 0; i < m; i ++) {
// for (int j = 0; j < n; j ++) {
// if (1 == mat[i][j]) {
// int step = bfs(mat, i, j);
// ans[i][j] = step;
// }
// }
// }
// return ans;
// }
// private int bfs(int[][] mat, int sr, int sc) {
// final int m = mat.length;
// final int n = mat[0].length;
// int step = -1;
// Queue<int[]> queue = new LinkedList<>();
// boolean[][] visited = new boolean[m][n];
// queue.offer(new int[]{sr, sc});
// visited[sr][sc] = true;
// while (!queue.isEmpty()) {
// int size = queue.size();
// step ++;
// for (int i = 0; i < size; i ++) {
// int[] curNode = queue.poll();
// if (0 == mat[curNode[0]][curNode[1]]) {
// return step;
// }
// for (int d = 0; d < directions.length; d ++) {
// int x = curNode[0] + directions[d][0];
// int y = curNode[1] + directions[d][1];
// if (x < 0 || x >= m || y < 0 || y >= n || visited[x][y]) {
// continue;
// }
// visited[x][y] = true;
// queue.offer(new int[]{x, y});
// }
// }
// }
// return step;
// }
// }
// 超时版本
class Solution {
private int[][] directions = new int[][]{
{-1, 0}, {1, 0}, {0, 1}, {0, -1}
};
public int[][] updateMatrix(int[][] mat) {
final int m = mat.length;
final int n = mat[0].length;
int step = 0;
Queue<int[]> queue = new LinkedList<>();
boolean[][] visited = new boolean[m][n];
int[][] ans = new int[m][n];
for (int i = 0; i < m; i ++) {
for (int j = 0; j < n; j ++) {
if (0 == mat[i][j]) {
queue.offer(new int[]{i, j});
visited[i][j] = true;
}
}
}
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i ++) {
int[] curNode = queue.poll();
if (1 == mat[curNode[0]][curNode[1]]) {
ans[curNode[0]][curNode[1]] = step;
}
for (int d = 0; d < directions.length; d ++) {
int x = curNode[0] + directions[d][0];
int y = curNode[1] + directions[d][1];
if (x < 0 || x >= m || y < 0 || y >= n || visited[x][y]) {
continue;
}
visited[x][y] = true;
queue.offer(new int[]{x, y});
}
}
step ++;
}
return ans;
}
}
841. 钥匙和房间
题解:
class Solution {
public boolean canVisitAllRooms(List<List<Integer>> rooms) {
final int n = rooms.size();
boolean[] visited = new boolean[n];
dfs(rooms, 0, visited);
boolean ans = true;
for (boolean v : visited) {
ans = (ans && v);
}
return ans;
}
private void dfs(List<List<Integer>> rooms, int index, boolean[] visited) {
visited[index] = true;
List<Integer> nodes = rooms.get(index);
for (Integer i : nodes) {
if (!visited[i]) {
dfs(rooms, i, visited);
}
}
}
}
547. 省份数量
题解:
class Solution {
public int findCircleNum(int[][] isConnected) {
final int m = isConnected.length;
boolean[] visited = new boolean[m];
int sum = 0;
for (int i = 0; i < m; i ++) {
if (!visited[i]) {
visited[i] = true;
sum ++;
dfs(isConnected, visited, i);
}
}
return sum;
}
private void dfs(int[][] isConnected, boolean[] visited, int i) {
final int n = isConnected.length;
for (int j = 0; j < n; j ++) {
if (!visited[j] && 1 == isConnected[i][j]) {
visited[j] = true;
dfs(isConnected, visited, j);
}
}
}
}
131. 分割回文串
题解:
class Solution {
public List<List<String>> partition(String s) {
final int len = s.length();
List<List<String>> res = new ArrayList<>();
boolean[][] dp = new boolean[len][len];
for (int right = 0; right < len; right ++) {
for (int left = 0; left <= right; left ++) {
if (s.charAt(left) == s.charAt(right) && (right - left <= 2 || dp[left + 1][right - 1])) {
dp[left][right] = true;
}
}
}
Deque<String> path = new ArrayDeque<>();
dfs(s, 0, len, dp, path, res);
return res;
}
private void dfs(String s, int start, int len, boolean[][] dp, Deque<String> path, List<List<String>> res) {
if (start == len) {
res.add(new ArrayList<>(path));
return;
}
for (int i = start; i < len; i ++) {
if (!dp[start][i]) {
continue;
}
path.addLast(s.substring(start, i + 1));
dfs(s, i + 1, len, dp, path, res);
path.removeLast();
}
}
}
1091. 二进制矩阵中的最短路径
题解:
class Solution {
private int[][] directions = new int[][]{
{-1, -1}, {-1, 0}, {-1, 1},
{0, -1}, {0, 1},
{1, -1}, {1, 0}, {1, 1}
};
public int shortestPathBinaryMatrix(int[][] grid) {
final int m = grid.length;
final int n = grid[0].length;
Queue<int[]> queue = new LinkedList<>();
if (1 == grid[0][0] || 1 == grid[m - 1][n - 1]) {
return -1;
}
boolean[][] visited = new boolean[m][n];
queue.offer(new int[]{0, 0});
visited[0][0] = true;
int step = 0;
while (!queue.isEmpty()) {
int size = queue.size();
step ++;
for (int i = 0; i < size; i ++) {
int[] curNode = queue.poll();
int x = curNode[0];
int y = curNode[1];
if (x == m - 1 && y == n - 1) {
return step;
}
for (int d = 0; d < directions.length; d ++) {
int curX = x + directions[d][0];
int curY = y + directions[d][1];
if (curX < 0 || curX >= m || curY < 0 || curY >= n || visited[curX][curY] || 1 == grid[curX][curY]) {
continue;
}
visited[curX][curY] = true;
queue.offer(new int[]{curX, curY});
}
}
}
return -1;
}
}