搜索类题目的高效实现
BFS 类问题
1 Surrounded Regions
public void surroundedRegions(char[][] board) { int n = board.length; if (n == 0) { return; } int m = board[0].length; for (int i = 0; i < m; i++) { bfs(board, 0, i); bfs(board, n - 1, i); } for (int i = 0; i < n; i++) { bfs(board, i, 0); bfs(board, i, m - 1); } for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (board[i][j] == 'O') { board[i][j] = 'X'; } else if (board[i][j] == '#') { board[i][j] = 'O'; } } } } void bfs(char[][] board, int i, int j) { if (board[i][j] != 'O') { return; } int[] dx = {1, -1, 0, 0}; int[] dy = {0, 0, -1, 1}; Queue<Integer> qx = new LinkedList<>(); Queue<Integer> qy = new LinkedList<>(); qx.offer(i); qy.offer(j); while (!qx.isEmpty()) { int cx = qx.poll(); int cy = qy.poll(); board[cx][cy] = '#'; for (int k = 0; k < dx.length; k++) { int nx = cx + dx[k]; int ny = cy + dy[k]; if (nx >= 0 && nx < board.length && ny >= 0 && ny < board[0].length && board[nx][ny] == 'O') { qx.offer(nx); qy.offer(ny); } } } }
2 Nearest Exit
public class MovingAvage { static final int INF = 2147483647; int n, m; public void wallsAndGates(int[][] rooms) { n = rooms.length; if (n == 0) { return; } m = rooms[0].length; int[] dx = {0, 0, -1, 1}; int[] dy = {-1, 1, 0, 1}; Queue<Integer> qx = new LinkedList<>(); Queue<Integer> qy = new LinkedList<>(); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (rooms[i][j] == 0) { qx.offer(i); qy.offer(j); } } } while (!qx.isEmpty()) { int cx = qx.poll(); int cy = qy.poll(); for (int i = 0; i < dx.length; i++) { int nx = cx + dx[i]; int ny = cy + dy[i]; if (0 <= nx && nx < n && 0 <= ny && ny < m && rooms[nx][ny] == INF) { qx.offer(nx); qy.offer(ny); rooms[nx][ny] = rooms[cx][cy] + 1; } } } }
3 17. Letter Combinations of a Phone Number
public List<String> letterCombinations(String digits) { String[] map = new String[] {"0", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; List<String> ans = new ArrayList<>(); if (digits.length() == 0) { return ans; } dfs(digits, 0, "", ans, map); return ans; } void dfs(String digits, int index, String item, List<String> ans, String[] map) { if (index == digits.length()) { ans.add(item); return; } int d = digits.charAt(index) - '0'; for (char c : map[d].toCharArray()) { dfs(digits, index + 1, item + c, ans, map); } }
4 Factorization
public List<List<Integer>> getFactors(int n) { List<List<Integer>> res = new ArrayList<>(); List<Integer> path = new ArrayList<>(); dfs(2, n, res, path); return res; } void dfs(int start, int remain, List<List<Integer>> res, List<Integer> path) { if (remain == 1) { if (path.size() != 1) { res.add(new ArrayList<>(path)); } return; } for (int i = start; i <= remain; i++) { if (i > remain / i) { break; } if (remain % i == 0) { path.add(i); dfs(start, remain / i, res, path); path.remove(path.size() - 1); } } path.add(remain); dfs(remain, 1); path.remove(path.size() - 1); }
5 Word Squares
public class MovingAvage { int wordLen; List<String> squares = new ArrayList<>(); Map<String, List<String>> hash = new HashMap<>(); List<List<String>> ans = new ArrayList<>(); public List<List<String>> wordSquares(String[] words) { if (words.length == 0) { return ans; } initPrefix(words); wordLen = words[0].length(); dfs(0); return ans; } private void dfs(int l) { // TODO Auto-generated method stub if (l == wordLen) { ans.add(new ArrayList<>(squares)); return; } String pre = ""; for (int i = 0; i < l; i++) { pre += squares.get(i).charAt(l); } List<String> w = hash.get(pre); for (String item : w) { if (!checkPrefix(l, item)) { continue; } squares.add(item); dfs(l + 1); squares.remove(squares.size() - 1); } } private boolean checkPrefix(int l, String item) { // TODO Auto-generated method stub for (int j = l + 1; j < wordLen; j++) { String pre = ""; for (int k = 0; k < l; k++) { pre = pre + squares.get(k).charAt(j); } pre += item.charAt(j); if (hash.containsKey(pre)) { return false; } } return true; } private void initPrefix(String[] words) { // TODO Auto-generated method stub for (String item : words) { if (!hash.containsKey("")) { hash.put("", new ArrayList<String>()); } hash.get("").add(item); String pre = ""; for (char c : item.toCharArray()) { pre += c; if (!hash.containsKey(pre)) { hash.put(pre, new ArrayList<String>()); } hash.get("pre").add(item); } } } }
6 Add Operators
String num; int target; List<String> res = new ArrayList<>(); public List<String> addOperators(String num, int target) { // write your code here this.num = num; this.target = target; dfs(0, "", 0, 0); return res; } void dfs(int start, String item, long sum, long last) { if (start == num.length()) { if (sum == target) { res.add(item); } return; } for (int i = start; i < num.length(); i++) { long x = Long.parseLong(num.substring(start, i + 1)); if (start == 0) { dfs(i + 1, "" + x, x, x); } else { dfs(i + 1, item + "+" + x, sum + x, x); dfs(i + 1, item + "-" + x, sum - x, -x); dfs(i + 1, item + "*" + x, sum - last + last * x, last * x); } if (x == 0) { break; } } }