刷题-回溯算法

 刷题顺序参考代码随想录代码随想录 (programmercarl.com)

目录

组合77. 组合 - 力扣(LeetCode)

相加总和组合216. 组合总和 III - 力扣(LeetCode)

(多数组)电话号码的字母组合17. 电话号码的字母组合 - 力扣(LeetCode)

无数量要求无重复元素可重复选取39. 组合总和 - 力扣(LeetCode)

无数量要求有重复元素不可重40. 组合总和 II - 力扣(LeetCode)

分割回文串131. 分割回文串 - 力扣(LeetCode)

复原IP地址93. 复原 IP 地址 - 力扣(LeetCode)

互不相同求子集78. 子集 - 力扣(LeetCode)

有重复选取子集90. 子集 II - 力扣(LeetCode)

有重复元素491. 非递减子序列 - 力扣(LeetCode)

无重复全排列46. 全排列 - 力扣(LeetCode)

有重复全排列47. 全排列 II - 力扣(LeetCode)


模板:

void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }

    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
        处理节点;
        backtracking(路径,选择列表); // 递归
        回溯,撤销处理结果
    }
}

组合77. 组合 - 力扣(LeetCode)

class Solution {
    List<List<Integer>> result=new ArrayList<>();
    LinkedList<Integer> path = new LinkedList<>();
    public void backtracking(int n,int k,int start){
        if(path.size()==k){
            result.add(new ArrayList<>(path));
            return;
        }
        for(int i=start;i<=n-(k-path.size())+1;i++){
            path.add(i);
            backtracking(n,k,i+1);
            path.removeLast();
        }
    }
    public List<List<Integer>> combine(int n, int k) {
        backtracking(n,k,1);
        return result;
    }
}

相加总和组合216. 组合总和 III - 力扣(LeetCode)

class Solution {
    List<List<Integer>> result=new ArrayList<>();
    LinkedList<Integer> path = new LinkedList<>();
    int sum;
    public void backtracking(int n,int k,int start){
        if(sum>n){
            return;
        }
        if(path.size()==k){
            if(sum==n){
                result.add(new ArrayList<>(path));
            }
            return;
        }
        for(int i=start;i<=9-(k-path.size())+1;i++){
            path.add(i);
            sum+=i;
            backtracking(n,k,i+1);
            sum-=path.getLast();
            path.removeLast();
        }
    }
    public List<List<Integer>> combinationSum3(int k, int n) {
        sum=0;
        backtracking(n,k,1);
        return result;
    }
}

(多数组)电话号码的字母组合17. 电话号码的字母组合 - 力扣(LeetCode)

class Solution {
    List<String> list = new ArrayList<>();
    public List<String> letterCombinations(String digits) {
        if(digits==null || digits.length()==0){
            return list;
        }
        //初始对应所有的数字,为了直接对应2-9,新增了两个无效的字符串""
        String[] numString = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
        backtracking(digits,numString,0);
        return list;
    }
    //每次迭代获取一个字符串,所以会设计大量的字符串拼接,所以这里选择更为高效的 StringBuild
    StringBuilder temp = new StringBuilder();
    public void backtracking(String digits,String[] numString,int num){
        if(temp.length()==digits.length()){
            list.add(temp.toString());
            return;
        }
        //str 表示当前num对应的字符串
        String str = numString[digits.charAt(num) - '0'];
        for(int i=0;i<str.length();i++){
            temp.append(str.charAt(i));
            backtracking(digits,numString,num+1);
            temp.deleteCharAt(temp.length()-1);
        }
    }
}

无数量要求无重复元素可重复选取39. 组合总和 - 力扣(LeetCode)

class Solution {
    List<List<Integer>> result=new ArrayList<>();
    LinkedList<Integer> path = new LinkedList<>();
    int sum;
    public void backtracking(int[] candidates,int target,int start){
        if(sum>target){
            return;
        }
        if(sum==target){
            result.add(new ArrayList<>(path));
            return;
        }
        for(int i=start;i<candidates.length;i++){
            path.add(candidates[i]);
            sum+=candidates[i];
            backtracking(candidates,target,start);
            sum-=path.getLast();
            path.removeLast();
            start++;
        }
    }
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        sum=0;
        Arrays.sort(candidates); // 先进行排序
        backtracking(candidates,target,0);
        return result;
    }
    
}

无数量要求有重复元素不可重40. 组合总和 II - 力扣(LeetCode)

class Solution {
    List<List<Integer>> result=new ArrayList<>();
    LinkedList<Integer> path = new LinkedList<>();
    int sum;
    public void backtracking(int[] candidates,int target,int start){
        if(sum>target){
            return;
        }
        if(sum==target){
            result.add(new ArrayList<>(path));
            return;
        }
        for(int i=start;i<candidates.length;i++){
            if(i>start && candidates[i] == candidates[i-1]){
                continue;
            }
            path.add(candidates[i]);
            sum+=candidates[i];
            backtracking(candidates,target,i+1);
            sum-=path.getLast();
            path.removeLast();
            
        }
    }
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        sum=0;
        Arrays.sort(candidates); // 先进行排序
        backtracking(candidates,target,0);
        return result;
    }
}

分割回文串131. 分割回文串 - 力扣(LeetCode)

class Solution {
    public boolean isHuiwen(String s,int start,int end){
        for(int i=start,j=end;i<j;i++,j--){
            if(s.charAt(i)!=s.charAt(j)){
                return false;
            }
        }
        return true;
    }
    List<List<String>> result=new ArrayList<>();
    LinkedList<String> path = new LinkedList<>();
    public void backTracking(String s,int start){
        if(start>=s.length()){
            result.add(new ArrayList(path));
            return;
        }
        for(int i=start;i<s.length();i++){
            if(isHuiwen(s,start,i)){
                String str= s.substring(start, i+1);
                path.addLast(str);
            } else {
                continue;
            }
            backTracking(s,i+1);
            path.removeLast();
        }
    }
    public List<List<String>> partition(String s) {
        if(s==null || s.length()==0){
            return result;
        }
        backTracking(s,0);
        return result;
    }
}

复原IP地址93. 复原 IP 地址 - 力扣(LeetCode)

class Solution {
    public boolean isHefa(String s){
        if(s.length()>1 && s.charAt(0)=='0'){
            return false;
        }else if(s.length()<1){
            return false;
        }
        else{
            int num=0;
            for(int i=0;i<s.length();i++){
                num = num * 10 + (s.charAt(i) - '0');
            }
            if(num>255||num<0){
                return false;
            }
        }
        return true;
    }
    List<String> result = new ArrayList<>();
    String path = new String("");
    public void backTracking(String s,int start,int pointnum){
        if(pointnum==3){
            String str1= s.substring(start, s.length());
            if(isHefa(str1)){
                result.add(path+str1);
            }
            return;
        }
        for(int i=start;i<s.length();i++){
            String str= s.substring(start, i+1);
            if(isHefa(str)){
                str+='.';
                path+=str;
                pointnum++;
            }else{
                continue;
            }
            backTracking(s,i+1,pointnum);
            path=path.substring(0,path.length()-str.length());
            pointnum--;
        }
    }
    List<String> result1 = new ArrayList<>();
    public List<String> restoreIpAddresses(String s) {
        if(s.length()>12){
            return result;
        }
        backTracking(s,0,0);
        return result;
    }
}

互不相同求子集78. 子集 - 力扣(LeetCode)

class Solution {
    List<List<Integer>> result=new ArrayList<>();
    LinkedList<Integer> path=new LinkedList<>();
    public void backTracking(int []nums,int start,int k){
        if(path.size()==k){
            result.add(new ArrayList<>(path));
            return;
        }
        for(int i=start;i<nums.length;i++){
            path.add(nums[i]);
            backTracking(nums,i+1,k);
            path.removeLast();
        }
    }
    public List<List<Integer>> subsets(int[] nums) {
        for(int i=0;i<=nums.length;i++){
            backTracking(nums,0,i);
        }
        return result;
    }
}

有重复选取子集90. 子集 II - 力扣(LeetCode)

class Solution {
    List<List<Integer>> result=new ArrayList<>();
    LinkedList<Integer> path=new LinkedList<>();
    public void backTracking(int []nums,int start,int k){
        if(path.size()==k){
            result.add(new ArrayList<>(path));
            return;
        }
        for(int i=start;i<nums.length;i++){
            // 跳过当前树层使用过的、相同的元素
            if(i>start&&nums[i]==nums[i-1]){
                continue;
            }
            path.add(nums[i]);
            backTracking(nums,i+1,k);
            path.removeLast();
        }
    }
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        Arrays.sort(nums);
        for(int i=0;i<=nums.length;i++){
            backTracking(nums,0,i);
        }
        return result;
    }
}

有重复元素491. 非递减子序列 - 力扣(LeetCode)

class Solution {
    List<List<Integer>> result=new ArrayList<>();
    LinkedList<Integer> path=new LinkedList<>();
    public void backTracking(int []nums,int start,int k){
        if(path.size()==k){
            result.add(new ArrayList<>(path));
            return;
        }
        HashSet<Integer> hs = new HashSet<>();
        for(int i=start;i<nums.length;i++){
            // 跳过当前树层使用过的、相同的元素
            if(path.size()!=0&&nums[i]<path.getLast()||hs.contains(nums[i])){
                continue;
            }
            hs.add(nums[i]);
            path.add(nums[i]);
            backTracking(nums,i+1,k);
            if(path.size()!=0){
                path.removeLast();
            }
        }
    }
    public List<List<Integer>> findSubsequences(int[] nums) {
        for(int i=2;i<=nums.length;i++){
            backTracking(nums,0,i);
        }
        return result;
    }
}

无重复全排列46. 全排列 - 力扣(LeetCode)

class Solution {
    List<List<Integer>> result=new ArrayList<>();
    LinkedList<Integer> path = new LinkedList<>();
    HashSet<Integer> hs;
    public void backtracking(int []n){
        if(path.size()==n.length){
            result.add(new ArrayList<>(path));
            return;
        }
        for(int i=0;i<n.length;i++){
            if(hs.contains(n[i])){
                continue;
            }
            path.add(n[i]);
            hs.add(n[i]);
            backtracking(n);
            path.removeLast();
            hs.remove(n[i]);
        }
    }
    public List<List<Integer>> permute(int[] nums) {
        hs = new HashSet<>();
        backtracking(nums);
        return result;
    }
}

有重复全排列47. 全排列 II - 力扣(LeetCode)

class Solution {
    List<List<Integer>> result=new ArrayList<>();
    LinkedList<Integer> path=new LinkedList<>();
    boolean []used;
    public void backTracking(int []nums){
        if(path.size()==nums.length){
            result.add(new ArrayList<>(path));
            return;
        }
        HashSet<Integer> hs = new HashSet<>();
        for(int i=0;i<nums.length;i++){
            // 跳过当前树层使用过的、相同的元素
            if(used[i]||hs.contains(nums[i])){
                continue;
            }
            hs.add(nums[i]);
            path.add(nums[i]);
            used[i]=true;
            System.out.print("path=");
            System.out.println(path);
            backTracking(nums);
            path.removeLast();
            used[i]=false;
        }
    }
    public List<List<Integer>> permuteUnique(int[] nums) {
        used=new boolean[nums.length];
        Arrays.fill(used,Boolean.FALSE);
        backTracking(nums);
        return result;
    }
}

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值