LeetCode-Backtracking
17. Letter Combinations of a Phone Number 电话号码的字母组合
https://leetcode.com/problems/letter-combinations-of-a-phone-number/
题目:如果字符串包含来自2-9的数字,则返回数字可以表示的所有可能的字母组合。数字到字母的映射(就像在电话按钮上一样)如下所示。注意,1不映射到任何字母。
思路:
class Solution { private static final String[] KEYS = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" }; public List<String> letterCombinations(String digits) { List<String> res = new LinkedList<String>(); if(digits.equals("")) return res; combination("", digits, 0, res); return res; } private void combination(String prefix, String digits, int offset, List<String> res) { if (offset >= digits.length()) { res.add(prefix); return; } String letters = KEYS[(digits.charAt(offset) - '0')]; for (int i = 0; i < letters.length(); i++) { combination(prefix + letters.charAt(i), digits, offset + 1, res); } } }
22. Generate Parentheses 生成括号
https://leetcode.com/problems/generate-parentheses/
题目:给定n对括号,编写一个函数来生成所有格式正确的括号的组合。
思路:
class Solution { public List<String> generateParenthesis(int n) { List<String> res = new ArrayList<>(); generater(n, n, "", res); return res; } public void generater(int left, int right, String s, List<String> res) { if(left > right) return; if(left > 0) { generater(left-1, right, s + "(", res); } if(right > 0) { generater(left, right-1, s + ")", res); } if(left == 0 && right == 0) { res.add(s); return; } } }
37. Sudoku Solver 解答数独
https://leetcode.com/problems/sudoku-solver/
题目:编写一个程序,通过填充空单元格来解决数独难题。
思路:
39. Combination Sum 数字组合之和
https://leetcode.com/problems/combination-sum/
题目:给定一组候选数字(无重复项)和一个目标数字(目标),在候选数字中寻找和为目标数字的候选数字的唯一组合。数字可以重复选择。
思路:
class Solution { private List<List<Integer>> res; private List<Integer> cur; public List<List<Integer>> combinationSum(int[] candidates, int target) { res = new ArrayList<List<Integer>>(); cur = new ArrayList<Integer>(); helper(candidates, target, 0); return res; } private void helper(int[] candidates, int target, int i) { for(int n : cur) { System.out.print(n + " "); } System.out.println(); if (target == 0) { res.add(new ArrayList<>(cur)); } else if (target < 0) { return; } else { while (i < candidates.length) { // i -> lastIndex int candidate = candidates[i]; cur.add(candidate); helper(candidates, target - candidate, i); cur.remove(cur.size() - 1); i++; } } } }
40. Combination Sum II
https://leetcode.com/problems/combination-sum-ii/
题目:给定候选人编号(候选人)和目标号码(目标)的集合,在候选人号码之和为目标的候选人中查找所有唯一的组合。候选人中的每个数字只能在组合中使用一次。注:所有数字(包括目标)都是正整数。解决方案集不能包含重复的组合。
思路:
class Solution { public List<List<Integer>> combinationSum2(int[] candidates, int target) { List<List<Integer>> res = new ArrayList<List<Integer>>(); Arrays.sort(candidates); helper(res, new ArrayList<Integer>(), candidates, target, 0); return res; } private void helper(List<List<Integer>> res, List<Integer> cur, int[] candidates, int target, int start) { System.out.println(); if (target == 0) { res.add(new ArrayList<>(cur)); } else if (target < 0) { return; } else { for (int i = start; i < candidates.length; i++) { if(i > start && candidates[i] == candidates[i-1]) { /** skip duplicates */ continue; } int candidate = candidates[i]; cur.add(candidate); helper(res, cur, candidates, target - candidate, i+1); cur.remove(cur.size() - 1); } } } }
46. Permutations 排列
https://leetcode.com/problems/permutations/
题目:给定一个不同整数集合,返回所有可能的排列。
思路:
class Solution { public List<List<Integer>> permute(int[] nums) { List<List<Integer>> res = new ArrayList<>(); List<Integer> init = new ArrayList<>(); for(int i = 0; i < nums.length; i++) { init.add(nums[i]); } permutation(init, new ArrayList<>(), res); return res; } private void permutation(List<Integer> init, List<Integer> list, List<List<Integer>> res) { if(init.isEmpty()) { res.add(new ArrayList<>(list)); } else { for (int i = 0; i < init.size(); i++) { List<Integer> initD = new ArrayList<>(init); List<Integer> listD = new ArrayList<>(list); listD.add(initD.get(i)); initD.remove(i); permutation(initD, listD, res); } } } }
47. Permutations II 排列 II
https://leetcode.com/problems/permutations-ii/
题目:给定可能包含重复项的数字集合,则返回所有可能的唯一排列。
思路:
class Solution { public List<List<Integer>> permuteUnique(int[] nums) { List<List<Integer>> res = new ArrayList<List<Integer>>(); if(nums==null || nums.length==0) return res; boolean[] used = new boolean[nums.length]; List<Integer> list = new ArrayList<Integer>(); Arrays.sort(nums); dfs(nums, used, list, res); return res; } public void dfs(int[] nums, boolean[] used, List<Integer> list, List<List<Integer>> res){ if(list.size()==nums.length){ res.add(new ArrayList<Integer>(list)); return; } for(int i=0;i<nums.length;i++){ if(used[i]) continue; if(i>0 &&nums[i-1]==nums[i] && !used[i-1]) continue; used[i]=true; list.add(nums[i]); dfs(nums,used,list,res); used[i]=false; list.remove(list.size()-1); } } }
51. N-Queens N皇后问题
https://leetcode.com/problems/n-queens/
题目:在n×n棋盘上放置n个皇后,使得不会有两个皇后能够互相攻击的情况出现。
思路:
class Solution { public List<List<String>> solveNQueens(int n) { List<List<String>> result = new ArrayList<>(); char[][] board = new char[n][n]; for (int i=0; i<n; i++) { for (int j=0; j<n; j++) { board[i][j] = '.'; } } solveNQueens(n, 0, new int[n], board, result); return result; } public void solveNQueens(int n, int row, int[] occupied, char[][] board, List<List<String>> result) { // our goal if(row == n) { List<String> path = new ArrayList<>(); for (int i=0; i<n; i++) { path.add(String.valueOf(board[i])); } result.add(path); // return; } else { for(int col = 0; col < n; col++) { // our choice occupied[row] = col; board[row][col] = 'Q'; // our constraints if(isValid(occupied, row, col)) { solveNQueens(n, row+1, occupied, board, result); } // undo our choice board[row][col] = '.'; } } } public boolean isValid(int[] occupied, int row, int col) { for(int i = 0; i < row; i++) { if (occupied[i] == col || Math.abs(col - occupied[i]) == Math.abs(i - row)) { return false; } } return true; } }
52. N-Queens II N皇后问题 II
https://leetcode.com/problems/n-queens-ii/
题目:n皇后之谜是在n×n棋盘上放置n个皇后的问题,这样就不会有两个皇后互相攻击。
思路:
class Solution { public int totalNQueens(int n) { List<Integer> result = new ArrayList<>(); solveNQueens(new ArrayList<>(), result, n); return result.size(); } public void solveNQueens(List<Integer> cur, List<Integer> result, int n) { // our goal if(cur.size() == n) { result.add(1); // return; } for(int col = 0; col < n; col++) { if (!cur.contains(col)) { if (isValid(cur, col)) { continue; } cur.add(col); solveNQueens(cur, result, n); cur.remove(cur.size() - 1); } } } public boolean isValid(List<Integer> cur, int i) { int cur_row = cur.size(); int cur_col = i; for (int row = 0; row < cur.size(); row++) { if (Math.abs(cur_row - row) == Math.abs(cur_col - cur.get(row))) { return true; } } return false; } }
77. Combinations 组合
https://leetcode.com/problems/combinations/
题目:给定两个整数n和k,从1中返回所有可能的k数组合。n.
思路:
class Solution { public List<List<Integer>> combine(int n, int k) { List<List<Integer>> res = new ArrayList<>(); helper(n, k, new ArrayList<>(), res, 1); return res; } public void helper(int n, int k, List<Integer> list, List<List<Integer>> res, int start) { if(k == 0) { res.add(new ArrayList<>(list)); return; } for(int i = start; i <= n; i++) { list.add(i); helper(n, k-1, list, res, i+1); // 注意是i+1不是start+1,不然在第一层递归从2开始循环时start仍为1 list.remove(list.size()-1); } } }
131. Palindrome Partitioning 将字符串分割成回文
https://leetcode.com/problems/palindrome-partitioning/
题目:给定字符串s,分区的每个子字符串都是回文。返回s的所有可能的回文分区。
思路:注意 i 从 1 开始,到 s.length() 结束。
class Solution { public List<List<String>> partition(String s) { List<List<String>> res = new ArrayList<>(); if(s == null || s.length() == 0) return res; partitioning(s, new ArrayList<>(), res); return res; } public void partitioning(String s, List<String> step, List<List<String>> res) { // Base case if(s == null || s.length() == 0) { res.add(new ArrayList<>(step)); return; } for(int i = 1; i <= s.length(); i++) { String temp = s.substring(0, i); if(!isPalindrome(temp)) continue; // only do backtracking when current string is palindrome step.add(temp); // make a choose partitioning(s.substring(i, s.length()), step, res); // explore step.remove(step.size() - 1); // undo our choose } return; } public boolean isPalindrome(String s) { int left = 0, right = s.length() - 1; while(left <= right) { if(s.charAt(left) != s.charAt(right)) { return false; } left++; right--; } return true; } }

浙公网安备 33010602011771号