1. LeetCode 77. 组合
题目链接:https://leetcode.cn/problems/combinations/description/
文章链接:https://programmercarl.com/0077.组合.html
视频链接:https://www.bilibili.com/video/BV1ti4y1L7cv
思路:利用递归回溯的方式。
递归回溯树形图如下:
其中,每层代表该层递归的处理逻辑,深度是递归的层数。
解法:
class Solution {List<List<Integer>> res = new ArrayList<>();List<Integer> list = new ArrayList<>();public List<List<Integer>> combine(int n, int k) {int[] input = new int[n];for (int i=0;i<n;i++) {input[i] = i+1;}int startIndex = 0;backtracking(input,k,startIndex);return res;}public void backtracking(int[] input,int k,int startIndex) {if ( k == 0) {res.add(new ArrayList(list));return;}for (int i=startIndex;i<input.length;i++) {list.add(input[i]);// 处理当前节点backtracking(input,k-1,i+1);list.removeLast(); // 撤销当前节点}}
}
代码解析:
单层处理完当前节点,要记得撤销当前节点,即回溯。这样它才能在当层排除该处理节点,并对其他节点重新进行处理,进行相同的逻辑。
2. LeetCode 216.组合总和III
题目链接:https://leetcode.cn/problems/combination-sum-iii/description/
文章链接:https://programmercarl.com/0216.组合总和III.html
视频链接:https://www.bilibili.com/video/BV1wg411873x
思路:
和77一样。只是加了求和的判断。
解法:
class Solution {List<Integer> list = new ArrayList<>();List<List<Integer>> res = new ArrayList<>();int sum = 0;public List<List<Integer>> combinationSum3(int k, int n) {find(n,k,1);return res;}public void find(int n,int k,int startIndex) {if (list.size() == k && sum == n) {res.add(new ArrayList(list));return;}for (int i=startIndex;i<=9;i++) {// 处理节点list.add(i);sum+=i;find(n,k,i+1);// 撤销节点list.removeLast();sum-=i;}}
}
3. LeetCode 17.电话号码的字母组合
题目链接:https://leetcode.cn/problems/letter-combinations-of-a-phone-number/
文章链接:https://leetcode.cn/problems/letter-combinations-of-a-phone-number/
视频链接:https://www.bilibili.com/video/BV1yV4y1V7Ug
思路:
使用回溯,但是要注意每层处理的字母集合是不同的集合,因此,每层遍历集合时的索引都是从0开始。
解法:
class Solution {List<String> res = new ArrayList<>();String combin = "";public List<String> letterCombinations(String digits) {if (digits.length() == 0 || digits == null) {return res;}Map<Character,String> map = new HashMap<>();map.put('2',"abc");map.put('3',"def");map.put('4',"ghi");map.put('5',"jkl");map.put('6',"mno");map.put('7',"pqrs");map.put('8',"tuv");map.put('9',"wxyz");find(digits,0,map);return res;}public void find(String digits,int index,Map<Character,String> map) {// 终止条件if (index == digits.length()) {res.add(combin);return;}// 获取当前层的字母集合,即 当前数字对应的字母集合String letters = map.get(digits.charAt(index));// 遍历当前层的字母集合for (int i=0;i<letters.length();i++) {// 处理当前字母combin += letters.charAt(i);// 递归下一层find(digits,index+1,map);// 撤销当前字母 即回溯combin = combin.substring(0,combin.length()-1);}}
}