leetcode回溯刷题整理

这篇博客详细介绍了回溯算法在LeetCode中解决组合、组合总和、电话号码的字母组合等典型问题的应用。通过实例分析了回溯算法的剪枝策略、边界条件和处理结果的方式,强调了剪枝在提高算法效率中的关键作用,并探讨了有无重复元素时的不同处理方法。
摘要由CSDN通过智能技术生成

回溯就是已经没什么别的办法了,回溯=暴力搜索,它相当于构建了一颗超大的树,然后每个叶子节点都是一种可能性,如果可能性符合条件,就要
回溯函数:
1.剪枝+如果到达最终状态,处理结果
2.元素进入与回退
比如说下面那个题,组合,给了一个k,k不确定,那就没法写for循环,只能回溯
回溯算法效率:就是拼谁剪枝剪得好,谁边界条件限制的好

第77题. 组合

给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。
思路:回溯
达到最终状态:那就是放元素的队列长度为k
剪枝:要达到不重复,需要在函数中有一个标识符,以及i不能选择太大,导致如果最后面剩余个数,每个都入队也不能达到k。这些都在for循环中限制了
注:我for循环中剪枝i<= n - (k - deque.size()) + 1 和不剪枝的速度差了22ms

class Solution {
   
    List<List<Integer>> res = new LinkedList<>();
    Deque<Integer> deque = new LinkedList<>();
    public void backtracking(int n,int k,int startIndex){
   
        if(deque.size()==k){
   
            res.add(new LinkedList(deque));
            return;
        }
        for(int i=startIndex;i<= n - (k - deque.size()) + 1;i++){
   
            deque.offerLast(i);
            backtracking(n,k,i+1);
            deque.pollLast();
        }
    }
    public List<List<Integer>> combine(int n, int k) {
   
        backtracking(n,k,1);
        return res;
    }
}

第216题.组合总和III

回溯,就是要尽可能考虑全限制条件,剪枝条件,条件考虑的越全,算法性能越高
那么和上面的题相比,多了什么条件?
剪枝:如果deque长度达到n且和为k,加入结果集,如果和不为k,也要回退
如果长度未达到n且当前和超过k,剪枝
for循环中边界条件多了一个i<=9的限制

class Solution {
   
    List<List<Integer>> res = new LinkedList<>();
    Deque<Integer> deque = new LinkedList<>();
    int count = 0;
    public void backtracking(int n,int k,int startIndex){
   
        if(deque.size()==k){
   
            if(count==n) res.add(new LinkedList(deque));
            return;
        }        
        if(count>n-startIndex) return;
        for(int i=startIndex;i<= Math.min(n - (k - deque.size()) + 1,9);i++){
               
            deque.offerLast(i);
            count+=i;            
            backtracking(n,k,i+1);            
            deque.pollLast();
            count-=i;
        }
    }
    public List<List<Integer>> combinationSum3(int k, int n) {
   
        backtracking(n,k,1);
        return res;
    }
}

17.电话号码的字母组合

这个组合和最上面那个组合没有本质区别,只不过是组合怎么取值变了而已

class Solution {
   
    List<String> res = new LinkedList<>();
    Deque<Character> chars = new LinkedList<>();

    public void backtracking(String digits,int index,Map<Character, String> phonemap){
   
        if(digits.length()==0) return;
        if(chars.size()==digits.length()){
   
            StringBuilder str = new StringBuilder();
            for(char c:chars){
   
                str.append(c);
            }
            res.add(str.toString());
            return;
        }
        String phonechar = phonemap.get(digits.charAt(index));
        for(int i=0;i<phonechar.length();i++){
   
            chars.offerLast(phonechar.charAt(i));
            backtracking(digits,index+1,phonemap);
            chars.pollLast();
        }

    }

    public List<String> letterCombinations(String digits) {
   
    Map<Character, String> phoneMap = new HashMap<Character, String>() {
   {
   
            put('2', "abc");
            put('3', "def");
            put('4', "ghi");
            put('5', "jkl"</
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值