[编程题] LeetCode上的backTracking类型的题目-难度Medium
来源:互联网 发布:软件测试行业好吗 编辑:程序博客网 时间:2024/05/29 16:17
最近把LeetCode上的backTracking的题目做了一下,发现都是一个套路~
backTracking链接:https://leetcode.com/tag/backtracking/
还有几道比较难的Medium的题和Hard的题没做出来,后面会继续更新和加详细解法解释~
回溯的入门之子集-Subsets
这种题目都是使用这个套路,就是用一个循环去枚举当前所有情况,然后把元素加入,递归,再把元素移除
按照这个套路来做,可以解决backTracking的问题
public class Solution { public List<List<Integer>> subsets(int[] nums) { List<List<Integer>> res = new ArrayList<>(); backTracking(res, new ArrayList<>(), nums, 0); return res; } private void backTracking(List<List<Integer>> res, List<Integer> list, int[] nums, int start){ res.add(new ArrayList<>(list)); //第一步 满足条件的临时集合加入结果集 for(int i = start; i < nums.length; ++i){ //第二步for循环 遍历所有的元素 list.add(nums[i]); //第三步 元素加入临时集合 backTracking(res, list, nums, i + 1); //第四步 回溯 list.remove(list.size() - 1); //第五步 元素从临时集合移除 } }}
Subsets II
返回数组(里面有重复的数字)的不含重复结果的子集
public class Solution { public List<List<Integer>> subsetsWithDup(int[] nums) { List<List<Integer>> res = new ArrayList<>(); Arrays.sort(nums); backTracking(res, new ArrayList<>(), nums, 0); return res; } private void backTracking(List<List<Integer>> res, List<Integer> list, int[] nums, int start){ if(!res.contains(list)) res.add(new ArrayList<>(list)); //检查是否包含结果,不包含才加入 for(int i = start; i < nums.length; ++i){ list.add(nums[i]); backTracking(res, list, nums, i + 1); list.remove(list.size() - 1); } }}
Letter Combinations of a Phone Number
手机键盘拨号,给你一串数字,问对应手机九宫格的输入法有可能输出那些字符串。
手机键盘:
输入:
“23”
输出:
[“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”]
public class Solution { private String[] letter = new String[] {" ", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; public List<String> letterCombinations(String digits) { List<String> res = new ArrayList<>(); if(digits == null || digits.length() == 0) return res; char[] nums = digits.toCharArray(); backTracking(res, new StringBuilder(), nums, 0); return res; } private void backTracking(List<String> res, StringBuilder build, char[] nums, int start){ if(build.length() == nums.length) res.add(build.toString()); for(int i = start; i < nums.length; ++i){ int index = Integer.parseInt(String.valueOf(nums[i])); for(int j = 0; j < letter[index].length(); ++j){ build.append(letter[index].charAt(j)); backTracking(res, build, nums, i + 1); build.deleteCharAt(build.length() - 1); } } }}
Generate Parentheses 括号生成器
public class Solution { public List<String> generateParenthesis(int n) { List<String> res = new ArrayList<>(); backTracking(res, new StringBuilder(), 0, 0, n); return res; } private void backTracking(List<String> res, StringBuilder builder, int left, int right, int n){ if(builder.length() == n*2) res.add(builder.toString()); else { if(left < n){ builder.append("("); backTracking(res, builder, left+1, right, n); builder.deleteCharAt(builder.length()-1); } if(right < n && left > right){ builder.append(")"); backTracking(res, builder, left, right+1, n); builder.deleteCharAt(builder.length()-1); } } }}
Combinations
给你两个整数n和k,返回在1到n个数里面所有可能的k个数字的组合。
public class Solution { public List<List<Integer>> combine(int n, int k) { List<List<Integer>> res = new ArrayList<>(); backTracking(res, new ArrayList<>(), n, k, 1); return res; } private void backTracking(List<List<Integer>> res, List<Integer> list, int n, int k, int start){ if(list.size() == k) res.add(new ArrayList(list)); for(int i = start; i <= n; ++i){ list.add(i); backTracking(res, list, n, k, i + 1); list.remove(list.size() - 1); } }}
Combination Sum
给定一个数组candidates,和一个整数target,返回所有candidates里面元素的组合的和等于target。对candidates里面的元素出现的次数无限制。
例如:
candidate : [2, 3, 6, 7] | target: 7
返回:
public class Solution { public List<List<Integer>> combinationSum(int[] candidates, int target) { List<List<Integer>> res = new ArrayList<>(); Arrays.sort(candidates); backTracking(res, new ArrayList<>(), candidates, target, 0); return res; } private void backTracking(List<List<Integer>> res, List<Integer> list, int[] candidate, int target, int start){ if(target < 0) return; if(target == 0) res.add(new ArrayList<>(list)); else { for(int i = start; i < candidate.length; ++i){ list.add(candidate[i]); backTracking(res, list, candidate, target - candidate[i], i); list.remove(list.size() - 1); } } }}
Combination Sum II
给定一个数组candidates,和一个整数target,返回所有candidates里面元素的组合的和等于target。对candidates里面的元素最多只能出现一次。
例如:
candidate : [10, 1, 2, 7, 6, 1, 5]
target: 8
返回:
public class Solution { public List<List<Integer>> combinationSum2(int[] candidates, int target) { List<List<Integer>> res = new ArrayList<>(); Arrays.sort(candidates); backTracking(res, new ArrayList<>(), candidates, target, 0); return res; } private void backTracking(List<List<Integer>> res, List<Integer> list, int[] candidate, int target, int start){ if(target < 0) return; if(target == 0) res.add(new ArrayList<>(list)); else { for(int i = start; i < candidate.length; ++i){ if(i > start && candidate[i] == candidate[i - 1]) continue; list.add(candidate[i]); backTracking(res, list, candidate, target - candidate[i], i + 1); list.remove(list.size() - 1); } } }}
Combination Sum III
public class Solution { public List<List<Integer>> combinationSum3(int k, int n) { List<List<Integer>> res = new ArrayList<>(); backTracking(res, new ArrayList<>(), k, n, 1); return res; } private void backTracking(List<List<Integer>> res, List<Integer> list, int k, int n, int start){ if(n < 0) return; if(n == 0 && list.size() == k) res.add(new ArrayList<>(list)); for(int i = start; i <= 9; i++){ list.add(i); backTracking(res, list, k, n-i, i+1); list.remove(list.size()-1); } }}
Permutations 排列
给你一个数字不重复的数组,求这个数组的所有排列
public class Solution { public List<List<Integer>> permute(int[] nums) { List<List<Integer>> res = new ArrayList<>(); backTracking(res, new ArrayList<>(), nums); return res; } private void backTracking(List<List<Integer>> res, List<Integer> list, int[] nums){ if(list.size() == nums.length) res.add(new ArrayList<>(list)); for(int i = 0; i < nums.length; ++i){ if(list.contains(nums[i])) continue; // 跳过重复的 list.add(nums[i]); backTracking(res, list, nums); list.remove(list.size() - 1); } }}
Palindrome Partitioning 分割回文字串
给你一个字符串s,分割字符串s使得每个子字符串都是回文,返回所有的分割结果。
如s = “aab”
返回:
[
[“aa”,”b”],
[“a”,”a”,”b”]
]
public class Solution { public List<List<String>> partition(String s) { List<List<String>> res = new ArrayList<>(); backTracking(res, new ArrayList<>(), s, 0); return res; } private void backTracking(List<List<String>> res, List<String> list, String s, int start){ if(start == s.length()) res.add(new ArrayList<>(list)); //start == s.length()的时候,说明已经带s的最后一个字符了 else { for(int i = start; i < s.length(); i++){ if(isPalindrome(s, start, i)){ list.add(s.substring(start, i+1)); backTracking(res, list, s, i+1); list.remove(list.size() - 1); } } } } /* * 判断是否是回文 */ private boolean isPalindrome(String s, int low, int high){ while(low < high){ if(s.charAt(low++) != s.charAt(high--)) return false; } return true; }}
N-Queens
有了 Palindrome Partitioning 分割回文字串 的基础,我们就可以解决经典的 N-皇后 的问题了: N-Queens
设计一种算法,打印n皇后在n*n棋盘上的各种摆法,其中每个皇后都不同行,不同列,也不在对角线上。
public class Solution { public List<List<String>> solveNQueens(int n) { List<Integer[]> res = new ArrayList<>(); backTracking(res, new Integer[n], n, 0); //以下只是把皇后放置在棋盘上 List<List<String>> resList = new ArrayList<>(); for(Integer[] nums: res){ List<String> list = new ArrayList<>(); for(int i = 0; i < nums.length; i++){ StringBuilder sb = new StringBuilder(); for(int j = 0; j < n; j++){ if(j == nums[i]) sb.append("Q"); else sb.append("."); } list.add(sb.toString()); } resList.add(list); } return resList; } /* * queen[] 是表示:下表i代表第i行的第queen[i]列放置一个皇后 */ private void backTracking(List<Integer[]> res, Integer[] queen, int n, int start){ if(start == n) res.add(queen.clone()); else { for(int i = 0; i < n; i++){ //不是从start开始 if(checkValid(queen, start, i)){ queen[start] = i; backTracking(res, queen, n, start+1); //不是i+1,i只是和列有关 } } } } /* * 检查在位置(row1,col1)是否可以放置皇后 */ private boolean checkValid(Integer[] queen, int row1, int col1){ for(int row2 = 0; row2 < row1; row2++){ int col2 = queen[row2]; if(col2 == col1) return false; //两个皇后放置在同一列上 int colSize = Math.abs(col1 - col2); int rowSize = row1 - row2; if(colSize == rowSize) return false; //两个皇后放置在同一对角线上 } return true; }}
- [编程题] LeetCode上的backTracking类型的题目-难度Medium
- [编程题] LeetCode上的Palindrome(回文)类型的题目
- [编程题] LeetCode上的Tree类型的题目
- [编程题] LeetCode上的Dynamic Programming(动态规划)类型的题目
- [编程题] LeetCode上的Reservoir Sampling(蓄水池算法)类型的题目
- leetcode题目的难度和面试频率
- Leetcode各题目的难度以及出现频率分析
- LeetCode题目难度及面试出现的频率
- (Leetcode)backtracking回溯法 题目汇总
- LeetCode[127. Word Ladder] 题解 难度[medium]
- LeetCode[392. Is Subsequence] 难度[medium]
- LeetCode[377. Combination Sum IV] 难度[medium]
- leetcode解题笔记:backtracking类型解题思路
- LeetCode题目难度分布(含面试频率及使用的数据结构与算法)
- LeetCode题目难度分布(含面试频率及使用的数据结构与算法)
- LeetCode题目难度分布(含面试频率及使用的数据结构与算法)
- LeetCode题目难度分布(含面试频率及使用的数据结构与算法)
- Python 爬虫学习:爬取LeetCode的题目并且按照难度分类
- jrebel安装注意的问题
- 深入理解Java Servlet与Web容器之间的关系
- 自定义JSP中的Taglib标签中的Function函数
- c++ list, vector, map, set 区别与用法比较
- 锁相环PLL(一)Xilinx PLL IP核使用方法
- [编程题] LeetCode上的backTracking类型的题目-难度Medium
- 数据结构——队列篇
- Android中事件传递机制的总结
- 字符驱动之:控制
- 关于禁用IQKeyboardManager
- JPA @MappedSuperclass注解的使用说明
- android开发笔记 -摄像头开发
- 安卓APP中WebView页面中定义字体
- Linux Centos下安装与设置Vim编辑器和基本配置