当前位置: 首页 > article >正文

代码随想录day21 | leetcode 77.组合 77.组合 加剪枝操作 216.组合总和III

组合

对于startIndex的变化,如何实现增大于减小。关键在于进栈,于连续出栈,重新入栈。

  1. 第一次调用backtracking(3, 2, 1)

    • startIndex = 1
    • 进入for循环,i = 1
      • path.push_back(1)path变为[1]
      • 递归调用backtracking(3, 2, 2)→进栈
        • 栈: [backtracking(3, 2, 2)]
  2. 第二次调用backtracking(3, 2, 2)

    • startIndex = 2
    • 进入for循环,i = 2
      • path.push_back(2)path变为[1, 2]
      • 递归调用backtracking(3, 2, 3)→进栈
        • 栈: [backtracking(3, 2, 2), backtracking(3, 2, 3)]
  3. 第三次调用backtracking(3, 2, 3)

    • startIndex = 3

    • 进入for循环,i = 3

      • path.push_back(3)path变为[1, 2, 3]

      • path.size() == k → 找到一个组合

      • result.push_back(path)result变为[[1, 2, 3]]

      • 返回→出栈

        • 栈: [backtracking(3, 2, 2)]

        !!!栈内有2个未出栈,实现了StartIndex – 操作。

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

        for (int i = startIndex; i <= n; i++) {
            path.add(i);
            backtracking(n,k,i+1);
            path.removeLast();
        }
    }
}

组合优化

省去树的分支,剪枝的地方就在递归中每一层的for循环所选择的起始位置。

如果for循环选择的起始位置之后的元素个数 已经不足 我们需要的元素个数了,那么就没有必要搜索了。

优化过程如下:

已经选择的元素个数:path.size();

还需要的元素个数为: k - path.size();

在集合n中至多要从该起始位置 : n - (k - path.size()) + 1,开始遍历

为什么有个+1呢,因为包括起始位置,我们要是一个左闭的集合。

举个例子,n = 4,k = 3, 目前已经选取的元素为0(path.size为0),n - (k - 0) + 1 即 4 - ( 3 - 0) + 1 = 2。

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

        for (int i = startIndex; i <= n-(k-path.size())+1; i++) {//改动
            path.add(i);
            backtracking(n,k,i+1);
            path.removeLast();
        }
    }
}
组合总和III

题目:找出所有相加之和为 n 的 k 个数的组合,且满足下列条件:

只使用数字1到9
每个数字 最多使用一次
返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。

class Solution {
   
     List<List<Integer>> result = new ArrayList<>();
    LinkedList<Integer> path = new LinkedList<>();

    public List<List<Integer>> combinationSum3(int k, int n) {
          backtracking(n,k,0,1);
        return result;
    }

    public void backtracking(int n,int k ,int sum ,int startIndex){
        
        if (sum > n) {
			return;
		}

        if (path.size() == k){
            if(n == sum){
            result.add(new ArrayList<>(path));
            
            }
           
           return;
        }

        for (int i = startIndex; i <= 9 && sum + i <= n; i++) {

            path.add(i);
            sum += i;
            backtracking(n,k,sum,i+1);
           
            path.removeLast();
            sum -= i;
        }
    }
}

http://www.kler.cn/a/458882.html

相关文章:

  • SQL 总结
  • 如何在 API 设计中做到接口幂等
  • 【蓝桥杯——物联网设计与开发】拓展模块4 - 脉冲模块
  • 时间复杂度与空间复杂度计算方法介绍
  • Android14 CTS-R6和GTS-12-R2不能同时测试的解决方法
  • 打造RAG系统:四大向量数据库Milvus、Faiss、Elasticsearch、Chroma 全面对比与选型指南
  • [图形渲染]【Unity Shader】【游戏开发】 Shader数学基础17-法线变换基础与应用
  • Java:192 基于SSM框架的失物招领信息管理系统
  • debian12安装docker
  • Linux的进程替换以及基础IO
  • 初学stm32 --- 高级定时器PWM输入模式
  • Github 2024-12-26 Go开源项目日报 Top10
  • (二)当人工智能是一个函数时,怎么去训练它?
  • 【机器学习】机器学习的基本分类-半监督学习-Ladder Networks
  • 【day20】集合深入探讨
  • Optional类:避免NullPointerException
  • Go语言的字符串处理
  • 每天40分玩转Django:Django Channels
  • react-native键盘遮盖底部输入框问题修复
  • 对于多个网站的爬虫管理和配置支持
  • 前端处理跨域的几种方式
  • AI 加持下的智能家居行业:变革、挑战与机遇
  • 深度学习-78-大模型量化之Quantization Aware Training量化感知训练QAT
  • LeetCode每日三题(五)双指针
  • 基于PLC的电梯控制系统(论文+源码)
  • 从Huggingface下载的数据集为arrow格式,如何从本地路径读取arrow数据并输出样例