From cc269f8b5e45414bd2eb665db7b5306a5e6947af Mon Sep 17 00:00:00 2001 From: CyC2018 <1029579233@qq.com> Date: Sat, 9 Jun 2018 13:53:37 +0800 Subject: [PATCH] auto commit --- notes/Leetcode 题解.md | 511 +++++++++++++++++++++++------------------ 1 file changed, 291 insertions(+), 220 deletions(-) diff --git a/notes/Leetcode 题解.md b/notes/Leetcode 题解.md index dca12b0d..dedc443c 100644 --- a/notes/Leetcode 题解.md +++ b/notes/Leetcode 题解.md @@ -1042,7 +1042,7 @@ private void swap(int[] nums, int i, int j) { - 4 -> {} - 3 -> {} -可以看到,每一轮遍历的节点都与根节点距离相同。设 di 表示第 i 个节点与根节点的距离,推导出一个结论:对于先遍历的节点 i 与后遍历的节点 j,有 di<=dj。利用这个结论,可以求解最短路径等 **最优解** 问题:第一次遍历到目的节点,其所经过的路径为最短路径。应该注意的是,使用 BFS 只能求解无权图的最短路径。 +可以看到,每一层遍历的节点都与根节点距离相同。设 di 表示第 i 个节点与根节点的距离,推导出一个结论:对于先遍历的节点 i 与后遍历的节点 j,有 di<=dj。利用这个结论,可以求解最短路径等 **最优解** 问题:第一次遍历到目的节点,其所经过的路径为最短路径。应该注意的是,使用 BFS 只能求解无权图的最短路径。 在程序实现 BFS 时需要考虑以下问题: @@ -1058,14 +1058,14 @@ private void swap(int[] nums, int i, int j) { [1,0,1,1]] ``` -题目描述:1 表示可以经过某个位置,求解从 (0, 0) 位置到 (tr, tc) 位置的最短路径长度。 +1 表示可以经过某个位置,求解从 (0, 0) 位置到 (tr, tc) 位置的最短路径长度。 ```java public int minPathLength(int[][] grids, int tr, int tc) { final int[][] direction = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; final int m = grids.length, n = grids[0].length; Queue> queue = new LinkedList<>(); - queue.add(new Pair(0, 0)); + queue.add(new Pair<>(0, 0)); int pathLength = 0; while (!queue.isEmpty()) { int size = queue.size(); @@ -1073,12 +1073,17 @@ public int minPathLength(int[][] grids, int tr, int tc) { while (size-- > 0) { Pair cur = queue.poll(); for (int[] d : direction) { - Pair next = new Pair(cur.getKey() + d[0], cur.getValue() + d[1]); - if (next.getKey() < 0 || next.getValue() >= m || next.getKey() < 0 || next.getValue() >= n) + int nr = cur.getKey() + d[0], nc = cur.getValue() + d[1]; + Pair next = new Pair<>(nr, nc); + if (next.getKey() < 0 || next.getValue() >= m + || next.getKey() < 0 || next.getValue() >= n) { + continue; + } grids[next.getKey()][next.getValue()] = 0; // 标记 - if (next.getKey() == tr && next.getValue() == tc) + if (next.getKey() == tr && next.getValue() == tc) { return pathLength; + } queue.add(next); } } @@ -1095,7 +1100,7 @@ public int minPathLength(int[][] grids, int tr, int tc) { For example, given n = 12, return 3 because 12 = 4 + 4 + 4; given n = 13, return 2 because 13 = 4 + 9. ``` -可以将每个整数看成图中的一个节点,如果两个整数只差为一个平方数,那么这两个整数所在的节点就有一条边。 +可以将每个整数看成图中的一个节点,如果两个整数之差为一个平方数,那么这两个整数所在的节点就有一条边。 要求解最小的平方数数量,就是求解从节点 n 到节点 0 的最短路径。 @@ -1108,20 +1113,23 @@ public int numSquares(int n) { boolean[] marked = new boolean[n + 1]; queue.add(n); marked[n] = true; - int num = 0; + int level = 0; while (!queue.isEmpty()) { int size = queue.size(); - num++; + level++; while (size-- > 0) { int cur = queue.poll(); for (int s : squares) { int next = cur - s; - if (next < 0) + if (next < 0) { break; - if (next == 0) - return num; - if (marked[next]) + } + if (next == 0) { + return level; + } + if (marked[next]) { continue; + } marked[next] = true; queue.add(cur - s); } @@ -1130,6 +1138,10 @@ public int numSquares(int n) { return n; } +/** + * 生成小于 n 的平方数序列 + * @return 1,4,9,... + */ private List generateSquares(int n) { List squares = new ArrayList<>(); int square = 1; @@ -1170,7 +1182,7 @@ Output: 0 Explanation: The endWord "cog" is not in wordList, therefore no possible transformation. ``` -题目描述:要找出一条从 beginWord 到 endWord 的最短路径,每次移动规定为改变一个字符,并且改变之后的字符串必须在 wordList 中。 +找出一条从 beginWord 到 endWord 的最短路径,每次移动规定为改变一个字符,并且改变之后的字符串必须在 wordList 中。 ```java public int ladderLength(String beginWord, String endWord, List wordList) { @@ -1178,10 +1190,12 @@ public int ladderLength(String beginWord, String endWord, List wordList) int N = wordList.size(); int start = N - 1; int end = 0; - while (end < N && !wordList.get(end).equals(endWord)) + while (end < N && !wordList.get(end).equals(endWord)) { end++; - if (end == N) + } + if (end == N) { return 0; + } List[] graphic = buildGraphic(wordList); return getShortestPath(graphic, start, end); } @@ -1192,8 +1206,9 @@ private List[] buildGraphic(List wordList) { for (int i = 0; i < N; i++) { graphic[i] = new ArrayList<>(); for (int j = 0; j < N; j++) { - if (isConnect(wordList.get(i), wordList.get(j))) + if (isConnect(wordList.get(i), wordList.get(j))) { graphic[i].add(j); + } } } return graphic; @@ -1202,8 +1217,9 @@ private List[] buildGraphic(List wordList) { private boolean isConnect(String s1, String s2) { int diffCnt = 0; for (int i = 0; i < s1.length() && diffCnt <= 1; i++) { - if (s1.charAt(i) != s2.charAt(i)) + if (s1.charAt(i) != s2.charAt(i)) { diffCnt++; + } } return diffCnt == 1; } @@ -1220,10 +1236,12 @@ private int getShortestPath(List[] graphic, int start, int end) { while (size-- > 0) { int cur = queue.poll(); for (int next : graphic[cur]) { - if (next == end) + if (next == end) { return path; - if (marked[next]) + } + if (marked[next]) { continue; + } marked[next] = true; queue.add(next); } @@ -1268,29 +1286,29 @@ private int m, n; private int[][] direction = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; public int maxAreaOfIsland(int[][] grid) { - if (grid == null || grid.length == 0) + if (grid == null || grid.length == 0) { return 0; - + } m = grid.length; n = grid[0].length; - int maxArea = 0; - for (int i = 0; i < m; i++) - for (int j = 0; j < n; j++) + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { maxArea = Math.max(maxArea, dfs(grid, i, j)); - + } + } return maxArea; } private int dfs(int[][] grid, int r, int c) { - if (r < 0 || r >= m || c < 0 || c >= n || grid[r][c] == 0) + if (r < 0 || r >= m || c < 0 || c >= n || grid[r][c] == 0) { return 0; - + } grid[r][c] = 0; int area = 1; - for (int[] d : direction) + for (int[] d : direction) { area += dfs(grid, r + d[0], c + d[1]); - + } return area; } ``` @@ -1316,29 +1334,31 @@ private int m, n; private int[][] direction = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; public int numIslands(char[][] grid) { - if (grid == null || grid.length == 0) + if (grid == null || grid.length == 0) { return 0; - + } m = grid.length; n = grid[0].length; int islandsNum = 0; - for (int i = 0; i < m; i++) - for (int j = 0; j < n; j++) + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { if (grid[i][j] != '0') { dfs(grid, i, j); islandsNum++; } - + } + } return islandsNum; } private void dfs(char[][] grid, int i, int j) { - if (i < 0 || i >= m || j < 0 || j >= n || grid[i][j] == '0') + if (i < 0 || i >= m || j < 0 || j >= n || grid[i][j] == '0') { return; - + } grid[i][j] = '0'; - for (int[] d : direction) + for (int[] d : direction) { dfs(grid, i + d[0], j + d[1]); + } } ``` @@ -1365,20 +1385,22 @@ public int findCircleNum(int[][] M) { n = M.length; int circleNum = 0; boolean[] hasVisited = new boolean[n]; - for (int i = 0; i < n; i++) + for (int i = 0; i < n; i++) { if (!hasVisited[i]) { dfs(M, i, hasVisited); circleNum++; } - + } return circleNum; } private void dfs(int[][] M, int i, boolean[] hasVisited) { hasVisited[i] = true; - for (int k = 0; k < n; k++) - if (M[i][k] == 1 && !hasVisited[k]) + for (int k = 0; k < n; k++) { + if (M[i][k] == 1 && !hasVisited[k]) { dfs(M, k, hasVisited); + } + } } ``` @@ -1400,7 +1422,7 @@ X X X X X O X X ``` -题目描述:使得被 'X' 包围的 'O' 转换为 'X'。 +使被 'X' 包围的 'O' 转换为 'X'。 先填充最外侧,剩下的就是里侧了。 @@ -1409,8 +1431,9 @@ private int[][] direction = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; private int m, n; public void solve(char[][] board) { - if (board == null || board.length == 0) + if (board == null || board.length == 0) { return; + } m = board.length; n = board[0].length; @@ -1424,22 +1447,25 @@ public void solve(char[][] board) { dfs(board, m - 1, i); } - for (int i = 0; i < m; i++) + for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { - if (board[i][j] == 'T') + if (board[i][j] == 'T') { board[i][j] = 'O'; - else if (board[i][j] == 'O') + } else if (board[i][j] == 'O') { board[i][j] = 'X'; + } } + } } private void dfs(char[][] board, int r, int c) { - if (r < 0 || r >= m || c < 0 || c >= n || board[r][c] != 'O') + if (r < 0 || r >= m || c < 0 || c >= n || board[r][c] != 'O') { return; - + } board[r][c] = 'T'; - for (int[] d : direction) + for (int[] d : direction) { dfs(board, r + d[0], c + d[1]); + } } ``` @@ -1462,17 +1488,19 @@ Return: [[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]] (positions with parentheses in above matrix). ``` -题目描述:左边和上边是太平洋,右边和下边是大西洋,内部的数字代表海拔,海拔高的地方的水能够流到低的地方,求解水能够流到太平洋和大西洋的所有位置。 +左边和上边是太平洋,右边和下边是大西洋,内部的数字代表海拔,海拔高的地方的水能够流到低的地方,求解水能够流到太平洋和大西洋的所有位置。 ```java + private int m, n; private int[][] matrix; private int[][] direction = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; public List pacificAtlantic(int[][] matrix) { List ret = new ArrayList<>(); - if (matrix == null || matrix.length == 0) + if (matrix == null || matrix.length == 0) { return ret; + } m = matrix.length; n = matrix[0].length; @@ -1489,24 +1517,30 @@ public List pacificAtlantic(int[][] matrix) { dfs(m - 1, i, canReachA); } - for (int i = 0; i < m; i++) - for (int j = 0; j < n; j++) - if (canReachP[i][j] && canReachA[i][j]) + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (canReachP[i][j] && canReachA[i][j]) { ret.add(new int[]{i, j}); + } + } + } return ret; } private void dfs(int r, int c, boolean[][] canReach) { - if (canReach[r][c]) + if (canReach[r][c]) { return; - + } canReach[r][c] = true; for (int[] d : direction) { int nextR = d[0] + r; int nextC = d[1] + c; - if (nextR < 0 || nextR >= m || nextC < 0 || nextC >= n || matrix[r][c] > matrix[nextR][nextC]) + if (nextR < 0 || nextR >= m || nextC < 0 || nextC >= n + || matrix[r][c] > matrix[nextR][nextC]) { + continue; + } dfs(nextR, nextC, canReach); } } @@ -1536,25 +1570,28 @@ Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]. ``` ```java + private static final String[] KEYS = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; public List letterCombinations(String digits) { - List ret = new ArrayList<>(); - if (digits == null || digits.length() == 0) - return ret; - combination(new StringBuilder(), digits, ret); - return ret; + List combinations = new ArrayList<>(); + if (digits == null || digits.length() == 0) { + return combinations; + } + doCombination(new StringBuilder(), combinations, digits); + return combinations; } -private void combination(StringBuilder prefix, String digits, List ret) { +private void doCombination(StringBuilder prefix, List combinations, final String digits) { if (prefix.length() == digits.length()) { - ret.add(prefix.toString()); + combinations.add(prefix.toString()); return; } - String letters = KEYS[digits.charAt(prefix.length()) - '0']; + int curDigits = digits.charAt(prefix.length()) - '0'; + String letters = KEYS[curDigits]; for (char c : letters.toCharArray()) { prefix.append(c); // 添加 - combination(prefix, digits, ret); + doCombination(prefix, combinations, digits); prefix.deleteCharAt(prefix.length() - 1); // 删除 } } @@ -1572,27 +1609,30 @@ return ["255.255.11.135", "255.255.111.35"]. ```java public List restoreIpAddresses(String s) { List addresses = new ArrayList<>(); - StringBuilder path = new StringBuilder(); - doRestore(0, path, s, addresses); + StringBuilder tempAddress = new StringBuilder(); + doRestore(0, tempAddress, addresses, s); return addresses; } -private void doRestore(int k, StringBuilder path, String s, List addresses) { +private void doRestore(int k, StringBuilder tempAddress, List addresses, String s) { if (k == 4 || s.length() == 0) { - if (k == 4 && s.length() == 0) - addresses.add(path.toString()); + if (k == 4 && s.length() == 0) { + addresses.add(tempAddress.toString()); + } return; } for (int i = 0; i < s.length() && i <= 2; i++) { - if (i != 0 && s.charAt(0) == '0') + if (i != 0 && s.charAt(0) == '0') { break; + } String part = s.substring(0, i + 1); if (Integer.valueOf(part) <= 255) { - if (path.length() != 0) + if (tempAddress.length() != 0) { part = "." + part; - path.append(part); - doRestore(k + 1, path, s.substring(i + 1), addresses); - path.delete(path.length() - part.length(), path.length()); + } + tempAddress.append(part); + doRestore(k + 1, tempAddress, addresses, s.substring(i + 1)); + tempAddress.delete(tempAddress.length() - part.length(), tempAddress.length()); } } } @@ -1616,38 +1656,50 @@ word = "ABCB", -> returns false. ``` ```java -private static int[][] direction = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; +private final static int[][] direction = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}; private int m; private int n; public boolean exist(char[][] board, String word) { - if (word == null || word.length() == 0) + if (word == null || word.length() == 0) { return true; - if (board == null || board.length == 0 || board[0].length == 0) + } + if (board == null || board.length == 0 || board[0].length == 0) { return false; + } m = board.length; n = board[0].length; - boolean[][] visited = new boolean[m][n]; + boolean[][] hasVisited = new boolean[m][n]; - for (int i = 0; i < m; i++) - for (int j = 0; j < n; j++) - if (backtracking(board, visited, word, 0, i, j)) return true; + for (int r = 0; r < m; r++) { + for (int c = 0; c < n; c++) { + if (backtracking(0, r, c, hasVisited, board, word)) { + return true; + } + } + } return false; } -private boolean backtracking(char[][] board, boolean[][] visited, String word, int start, int r, int c) { - if (start == word.length()) +private boolean backtracking(int curLen, int r, int c, boolean[][] visited, final char[][] board, final String word) { + if (curLen == word.length()) { return true; - if (r < 0 || r >= m || c < 0 || c >= n || board[r][c] != word.charAt(start) || visited[r][c]) + } + if (r < 0 || r >= m || c < 0 || c >= n + || board[r][c] != word.charAt(curLen) || visited[r][c]) { + return false; + } visited[r][c] = true; - for (int[] d : direction) - if (backtracking(board, visited, word, start + 1, r + d[0], c + d[1])) + for (int[] d : direction) { + if (backtracking(curLen + 1, r + d[0], c + d[1], visited, board, word)) { return true; + } + } visited[r][c] = false; @@ -1672,22 +1724,25 @@ private boolean backtracking(char[][] board, boolean[][] visited, String word, i ``` ```java + public List binaryTreePaths(TreeNode root) { - List paths = new ArrayList(); - if (root == null) + List paths = new ArrayList<>(); + if (root == null) { return paths; + } List values = new ArrayList<>(); backtracking(root, values, paths); return paths; } private void backtracking(TreeNode node, List values, List paths) { - if (node == null) + if (node == null) { return; + } values.add(node.val); - if (isLeaf(node)) + if (isLeaf(node)) { paths.add(buildPath(values)); - else { + } else { backtracking(node.left, values, paths); backtracking(node.right, values, paths); } @@ -1702,8 +1757,9 @@ private String buildPath(List values) { StringBuilder str = new StringBuilder(); for (int i = 0; i < values.size(); i++) { str.append(values.get(i)); - if (i != values.size() - 1) + if (i != values.size() - 1) { str.append("->"); + } } return str.toString(); } @@ -1727,24 +1783,25 @@ private String buildPath(List values) { ```java public List> permute(int[] nums) { - List> ret = new ArrayList<>(); + List> permutes = new ArrayList<>(); List permuteList = new ArrayList<>(); - boolean[] visited = new boolean[nums.length]; - backtracking(permuteList, visited, nums, ret); - return ret; + boolean[] hasVisited = new boolean[nums.length]; + backtracking(permuteList, permutes, hasVisited, nums); + return permutes; } -private void backtracking(List permuteList, boolean[] visited, int[] nums, List> ret) { +private void backtracking(List permuteList, List> permutes, boolean[] visited, final int[] nums) { if (permuteList.size() == nums.length) { - ret.add(new ArrayList(permuteList)); // 重新构造一个 List + permutes.add(new ArrayList<>(permuteList)); // 重新构造一个 List return; } for (int i = 0; i < visited.length; i++) { - if (visited[i]) + if (visited[i]) { continue; + } visited[i] = true; permuteList.add(nums[i]); - backtracking(permuteList, visited, nums, ret); + backtracking(permuteList, permutes, visited, nums); permuteList.remove(permuteList.size() - 1); visited[i] = false; } @@ -1760,34 +1817,36 @@ private void backtracking(List permuteList, boolean[] visited, int[] nu [[1,1,2], [1,2,1], [2,1,1]] ``` -题目描述:数组元素可能含有相同的元素,进行排列时就有可能出现重复的排列,要求重复的排列只返回一个。 +数组元素可能含有相同的元素,进行排列时就有可能出现重复的排列,要求重复的排列只返回一个。 在实现上,和 Permutations 不同的是要先排序,然后在添加一个元素时,判断这个元素是否等于前一个元素,如果等于,并且前一个元素还未访问,那么就跳过这个元素。 ```java public List> permuteUnique(int[] nums) { - List> ret = new ArrayList<>(); + List> permutes = new ArrayList<>(); List permuteList = new ArrayList<>(); - Arrays.sort(nums); - boolean[] visited = new boolean[nums.length]; - backtracking(permuteList, visited, nums, ret); - return ret; + Arrays.sort(nums); // 排序 + boolean[] hasVisited = new boolean[nums.length]; + backtracking(permuteList, permutes, hasVisited, nums); + return permutes; } -private void backtracking(List permuteList, boolean[] visited, int[] nums, List> ret) { +private void backtracking(List permuteList, List> permutes, boolean[] visited, final int[] nums) { if (permuteList.size() == nums.length) { - ret.add(new ArrayList(permuteList)); + permutes.add(new ArrayList<>(permuteList)); return; } for (int i = 0; i < visited.length; i++) { - if (i != 0 && nums[i] == nums[i - 1] && !visited[i - 1]) - continue; // 防止重复 - if (visited[i]) + if (i != 0 && nums[i] == nums[i - 1] && !visited[i - 1]) { + continue; // 防止重复 + } + if (visited[i]){ continue; + } visited[i] = true; permuteList.add(nums[i]); - backtracking(permuteList, visited, nums, ret); + backtracking(permuteList, permutes, visited, nums); permuteList.remove(permuteList.size() - 1); visited[i] = false; } @@ -1812,21 +1871,20 @@ If n = 4 and k = 2, a solution is: ```java public List> combine(int n, int k) { - List> ret = new ArrayList<>(); + List> combinations = new ArrayList<>(); List combineList = new ArrayList<>(); - backtracking(1, n, k, combineList, ret); - return ret; + backtracking(combineList, combinations, 1, k, n); + return combinations; } -private void backtracking(int start, int n, int k, List combineList, List> ret) { +private void backtracking(List combineList, List> combinations, int start, int k, final int n) { if (k == 0) { - ret.add(new ArrayList(combineList)); + combinations.add(new ArrayList<>(combineList)); return; } - for (int i = start; i <= n - k + 1; i++) { // 剪枝 combineList.add(i); - backtracking(i + 1, n, k - 1, combineList, ret); + backtracking(combineList, combinations, i + 1, k - 1, n); combineList.remove(combineList.size() - 1); } } @@ -1844,21 +1902,23 @@ A solution set is: ```java public List> combinationSum(int[] candidates, int target) { - List> ret = new ArrayList<>(); - doCombination(candidates, target, 0, new ArrayList<>(), ret); - return ret; + List> combinations = new ArrayList<>(); + backtracking(new ArrayList<>(), combinations, 0, target, candidates); + return combinations; } -private void doCombination(int[] candidates, int target, int start, List list, List> ret) { +private void backtracking(List tempCombination, List> combinations, + int start, int target, final int[] candidates) { + if (target == 0) { - ret.add(new ArrayList<>(list)); + combinations.add(new ArrayList<>(tempCombination)); return; } for (int i = start; i < candidates.length; i++) { if (candidates[i] <= target) { - list.add(candidates[i]); - doCombination(candidates, target - candidates[i], i, list, ret); - list.remove(list.size() - 1); + tempCombination.add(candidates[i]); + backtracking(tempCombination, combinations, i, target - candidates[i], candidates); + tempCombination.remove(tempCombination.size() - 1); } } } @@ -1881,26 +1941,29 @@ A solution set is: ```java public List> combinationSum2(int[] candidates, int target) { - List> ret = new ArrayList<>(); + List> combinations = new ArrayList<>(); Arrays.sort(candidates); - doCombination(candidates, target, 0, new ArrayList<>(), new boolean[candidates.length], ret); - return ret; + backtracking(new ArrayList<>(), combinations, new boolean[candidates.length], 0, target, candidates); + return combinations; } -private void doCombination(int[] candidates, int target, int start, List list, boolean[] visited, List> ret) { +private void backtracking(List tempCombination, List> combinations, + boolean[] hasVisited, int start, int target, final int[] candidates) { + if (target == 0) { - ret.add(new ArrayList<>(list)); + combinations.add(new ArrayList<>(tempCombination)); return; } for (int i = start; i < candidates.length; i++) { - if (i != 0 && candidates[i] == candidates[i - 1] && !visited[i - 1]) + if (i != 0 && candidates[i] == candidates[i - 1] && !hasVisited[i - 1]) { continue; + } if (candidates[i] <= target) { - list.add(candidates[i]); - visited[i] = true; - doCombination(candidates, target - candidates[i], i + 1, list, visited, ret); - visited[i] = false; - list.remove(list.size() - 1); + tempCombination.add(candidates[i]); + hasVisited[i] = true; + backtracking(tempCombination, combinations, hasVisited, i + 1, target - candidates[i], candidates); + hasVisited[i] = false; + tempCombination.remove(tempCombination.size() - 1); } } } @@ -1918,27 +1981,30 @@ Output: [[1,2,6], [1,3,5], [2,3,4]] ``` -题目描述:从 1-9 数字中选出 k 个数不重复的数,使得它们的和为 n。 +从 1-9 数字中选出 k 个数不重复的数,使得它们的和为 n。 ```java public List> combinationSum3(int k, int n) { - List> ret = new ArrayList<>(); + List> combinations = new ArrayList<>(); List path = new ArrayList<>(); - backtracking(k, n, path, 1, ret); - return ret; + backtracking(k, n, 1, path, combinations); + return combinations; } -private void backtracking(int k, int n, List path, int start, List> ret) { +private void backtracking(int k, int n, int start, + List tempCombination, List> combinations) { + if (k == 0 && n == 0) { - ret.add(new ArrayList<>(path)); + combinations.add(new ArrayList<>(tempCombination)); return; } - if (k == 0 || n == 0) + if (k == 0 || n == 0) { return; + } for (int i = start; i <= 9; i++) { - path.add(i); - backtracking(k - 1, n - i, path, i + 1, ret); - path.remove(path.size() - 1); + tempCombination.add(i); + backtracking(k - 1, n - i, i + 1, tempCombination, combinations); + tempCombination.remove(tempCombination.size() - 1); } } ``` @@ -1947,29 +2013,29 @@ private void backtracking(int k, int n, List path, int start, List> ret; -private List subsetList; - public List> subsets(int[] nums) { - ret = new ArrayList<>(); - subsetList = new ArrayList<>(); - for (int i = 0; i <= nums.length; i++) // 不同的子集大小 - backtracking(0, i, nums); - return ret; + List> subsets = new ArrayList<>(); + List tempSubset = new ArrayList<>(); + for (int size = 0; size <= nums.length; size++) { + backtracking(0, tempSubset, subsets, size, nums); // 不同的子集大小 + } + return subsets; } -private void backtracking(int startIdx, int size, int[] nums) { - if (subsetList.size() == size) { - ret.add(new ArrayList(subsetList)); +private void backtracking(int start, List tempSubset, List> subsets, + final int size, final int[] nums) { + + if (tempSubset.size() == size) { + subsets.add(new ArrayList<>(tempSubset)); return; } - for (int i = startIdx; i < nums.length; i++) { - subsetList.add(nums[i]); - backtracking(i + 1, size, nums); - subsetList.remove(subsetList.size() - 1); + for (int i = start; i < nums.length; i++) { + tempSubset.add(nums[i]); + backtracking(i + 1, tempSubset, subsets, size, nums); + tempSubset.remove(tempSubset.size() - 1); } } ``` @@ -1993,35 +2059,33 @@ If nums = [1,2,2], a solution is: ``` ```java -private List> ret; -private List subsetList; -private boolean[] visited; - public List> subsetsWithDup(int[] nums) { - ret = new ArrayList<>(); - subsetList = new ArrayList<>(); - visited = new boolean[nums.length]; Arrays.sort(nums); - - for (int i = 0; i <= nums.length; i++) - backtracking(0, i, nums); - - return ret; + List> subsets = new ArrayList<>(); + List tempSubset = new ArrayList<>(); + boolean[] hasVisited = new boolean[nums.length]; + for (int size = 0; size <= nums.length; size++) { + backtracking(0, tempSubset, subsets, hasVisited, size, nums); // 不同的子集大小 + } + return subsets; } -private void backtracking(int startIdx, int size, int[] nums) { - if (subsetList.size() == size) { - ret.add(new ArrayList(subsetList)); +private void backtracking(int start, List tempSubset, List> subsets, boolean[] hasVisited, + final int size, final int[] nums) { + + if (tempSubset.size() == size) { + subsets.add(new ArrayList<>(tempSubset)); return; } - for (int i = startIdx; i < nums.length; i++) { - if (i != 0 && nums[i] == nums[i - 1] && !visited[i - 1]) + for (int i = start; i < nums.length; i++) { + if (i != 0 && nums[i] == nums[i - 1] && !hasVisited[i - 1]) { continue; - subsetList.add(nums[i]); - visited[i] = true; - backtracking(i + 1, size, nums); - visited[i] = false; - subsetList.remove(subsetList.size() - 1); + } + tempSubset.add(nums[i]); + hasVisited[i] = true; + backtracking(i + 1, tempSubset, subsets, hasVisited, size, nums); + hasVisited[i] = false; + tempSubset.remove(tempSubset.size() - 1); } } ``` @@ -2041,32 +2105,33 @@ Return ``` ```java -private List> ret; - public List> partition(String s) { - ret = new ArrayList<>(); - doPartition(new ArrayList<>(), s); - return ret; + List> partitions = new ArrayList<>(); + List tempPartition = new ArrayList<>(); + doPartition(s, partitions, tempPartition); + return partitions; } -private void doPartition(List list, String s) { +private void doPartition(String s, List> partitions, List tempPartition) { if (s.length() == 0) { - ret.add(new ArrayList<>(list)); + partitions.add(new ArrayList<>(tempPartition)); return; } for (int i = 0; i < s.length(); i++) { if (isPalindrome(s, 0, i)) { - list.add(s.substring(0, i + 1)); - doPartition(list, s.substring(i + 1)); - list.remove(list.size() - 1); + tempPartition.add(s.substring(0, i + 1)); + doPartition(s.substring(i + 1), partitions, tempPartition); + tempPartition.remove(tempPartition.size() - 1); } } } private boolean isPalindrome(String s, int begin, int end) { - while (begin < end) - if (s.charAt(begin++) != s.charAt(end--)) + while (begin < end) { + if (s.charAt(begin++) != s.charAt(end--)) { return false; + } + } return true; } ``` @@ -2087,17 +2152,20 @@ public void solveSudoku(char[][] board) { this.board = board; for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++) { - if (board[i][j] == '.') + if (board[i][j] == '.') { continue; + } int num = board[i][j] - '0'; rowsUsed[i][num] = true; colsUsed[j][num] = true; cubesUsed[cubeNum(i, j)][num] = true; } - for (int i = 0; i < 9; i++) - for (int j = 0; j < 9; j++) + for (int i = 0; i < 9; i++) { + for (int j = 0; j < 9; j++) { backtracking(i, j); + } + } } private boolean backtracking(int row, int col) { @@ -2105,17 +2173,18 @@ private boolean backtracking(int row, int col) { row = col == 8 ? row + 1 : row; col = col == 8 ? 0 : col + 1; } - - if (row == 9) + if (row == 9) { return true; - + } for (int num = 1; num <= 9; num++) { - if (rowsUsed[row][num] || colsUsed[col][num] || cubesUsed[cubeNum(row, col)][num]) + if (rowsUsed[row][num] || colsUsed[col][num] || cubesUsed[cubeNum(row, col)][num]) { continue; + } rowsUsed[row][num] = colsUsed[col][num] = cubesUsed[cubeNum(row, col)][num] = true; board[row][col] = (char) (num + '0'); - if (backtracking(row, col)) + if (backtracking(row, col)) { return true; + } board[row][col] = '.'; rowsUsed[row][num] = colsUsed[col][num] = cubesUsed[cubeNum(row, col)][num] = false; } @@ -2135,7 +2204,7 @@ private int cubeNum(int i, int j) {

-题目描述:在 n\*n 的矩阵中摆放 n 个皇后,并且每个皇后不能在同一行,同一列,同一对角线上,求所有的 n 皇后的解。 +在 n\*n 的矩阵中摆放 n 个皇后,并且每个皇后不能在同一行,同一列,同一对角线上,求所有的 n 皇后的解。 一行一行地摆放,在确定一行中的那个皇后应该摆在哪一列时,需要用三个标记数组来确定某一列是否合法,这三个标记数组分别为:列标记数组、45 度对角线标记数组和 135 度对角线标记数组。 @@ -2148,7 +2217,7 @@ private int cubeNum(int i, int j) {

```java -private List> ret; +private List> solutions; private char[][] nQueens; private boolean[] colUsed; private boolean[] diagonals45Used; @@ -2156,32 +2225,35 @@ private boolean[] diagonals135Used; private int n; public List> solveNQueens(int n) { - ret = new ArrayList<>(); + solutions = new ArrayList<>(); nQueens = new char[n][n]; - for(int i = 0; i < n; i++) + for (int i = 0; i < n; i++) { Arrays.fill(nQueens[i], '.'); + } colUsed = new boolean[n]; diagonals45Used = new boolean[2 * n - 1]; diagonals135Used = new boolean[2 * n - 1]; this.n = n; backtracking(0); - return ret; + return solutions; } private void backtracking(int row) { if (row == n) { List list = new ArrayList<>(); - for (char[] chars : nQueens) + for (char[] chars : nQueens) { list.add(new String(chars)); - ret.add(list); + } + solutions.add(list); return; } for (int col = 0; col < n; col++) { int diagonals45Idx = row + col; int diagonals135Idx = n - 1 - (row - col); - if (colUsed[col] || diagonals45Used[diagonals45Idx] || diagonals135Used[diagonals135Idx]) + if (colUsed[col] || diagonals45Used[diagonals45Idx] || diagonals135Used[diagonals135Idx]) { continue; + } nQueens[row][col] = 'Q'; colUsed[col] = diagonals45Used[diagonals45Idx] = diagonals135Used[diagonals135Idx] = true; backtracking(row + 1); @@ -2231,10 +2303,9 @@ public List diffWaysToCompute(String input) { } } } - - if (ways.size() == 0) + if (ways.size() == 0) { ways.add(Integer.valueOf(input)); - + } return ways; } ```