代码随想录算法训练营第24天25天|● 77. 组合● 216.组合总和III ● 17.电话号码的字母组合

news2024/12/29 16:12:30

77组合

看完题后的思路

在这里插入图片描述

  1. void f(数组,startIndex)
  2. 递归终止
    if(startIndex数组长度||path.sizek){
    if(path.size==k){
    加入}
    }
  3. 递归

for(;startIndex<num.size;startIndex++){
加入;
4.剪枝
if(path.size>k){
吐出来;
return;
}
f(num,startIndex+1);
// 回溯
吐出来

}

代码

 List<List<Integer>> ires = new ArrayList<>();
    ArrayList<Integer> ipath = new ArrayList<>();
    public List<List<Integer>> combine(int n, int k) {
        combineTB(n,0,k);
        return ires;
    }
    public void combineTB(int n,int startIndex,int k){
        //终止
        if (startIndex==n||ipath.size()==k){
            if (ipath.size()==k){
              ires.add(new ArrayList<>(ipath));
            }
            return;
        }
        for (; startIndex<n; startIndex++) {
            // 尝试加入
            ipath.add(startIndex);
            // 剪枝
            if (ipath.size()>k){  // 这一步永远不会生效,因为终止条件已经剪枝了
                return;
            }
            // 进入下一层
            combineTB(n,startIndex+1,k);
            // 回溯
            ipath.remove(ipath.size()-1);
            
            // 进入本层下一个 ----->
        }
    }

复杂度

优化:添加剪枝条件

      // 剪枝
            if (ipath.size()==k||n-startIndex+1<(k-ipath.size())){
                return;
            }

后一个剪枝条件表示当前可加入的元素<所缺的元素

在这里插入图片描述

List<List<Integer>> ires = new ArrayList<>();
    ArrayList<Integer> ipath = new ArrayList<>();
    public List<List<Integer>> combine(int n, int k) {
        combineTB(n,1,k);
        return ires;
    }
    public void combineTB(int n,int startIndex,int k){
        //终止
        if (startIndex>n||ipath.size()==k){
            if (ipath.size()==k){
              ires.add(new ArrayList<>(ipath));
            }
            return;
        }
        for (; startIndex<=n; startIndex++) {
                  // 剪枝
            if (ipath.size()==k||n-startIndex+1<(k-ipath.size())){
                return;
            }
            // 尝试加入
            ipath.add(startIndex);
            // 剪枝
            // if (ipath.size()>k){
            //     return;
            // }
            // 进入下一层
            combineTB(n,startIndex+1,k);
            // 回溯
            ipath.remove(ipath.size()-1);
            
            // 进入本层下一个 ----->
        }
    }

递归深度: k
递归宽度:n-startIndex+1<(k-ipath.size())
在这里插入图片描述

收获

  1. 三刷看一遍
  2. 组合问题模板
    在这里插入图片描述
  3. 做回溯题步骤
    (0)判断问题类型
    (1)树状图
    (2)递归三部曲
    (3)剪枝条件

216.组合总和III

看完题后的思路

a+b=b+a,这是一个组合问题
在这里插入图片描述

  1. void f(n,k,startIndex,sum) // 纵向剪枝
  2. 终止条件
    if(path.size==k){
    if(和为n){
    加入
    }
    return;
    }
  3. 回溯模型
  4. 剪枝条件
    if(path内的数+当前树大于k) return

代码

  List<List<Integer>> ires = new ArrayList<>();
    ArrayList<Integer> ipath = new ArrayList<>();
 //216. 组合总和 III
    public List<List<Integer>> combinationSum3(int k, int n) {
        combinationSum3BT(k,n,0,1);
        return ires;
    }

    public void combinationSum3BT(int k, int n,int sum,int startIndex ) {
        if(ipath.size()==k){// 终止+纵向剪枝
            if (sum==n){
                ires.add(new ArrayList<>(ipath));
            }
            return;
        }
        for (; startIndex <=9 ; startIndex++) {
            // 纵向剪枝
            if (startIndex+sum>n){
                return;  // (纵)横向剪枝  因为兄弟节点 (startIndex++)+sum也一定>k
            }
            sum+=startIndex;
            ipath.add(startIndex);
            combinationSum3BT(k,n,sum,startIndex+1);
            // 回溯
            sum-=startIndex;
            ipath.remove(ipath.size()-1);
            // 本层下一个
            
        }

    }

复杂度

最坏时间复杂度 0(9*k)
在这里插入图片描述

收获

1.本题让组合剪枝变得明朗,三刷大脑过一遍
2, 组合问题中的纵横剪枝
==有图==

17.电话号码的字母组合

看完题后的思路

在这里插入图片描述

  1. 本体可以抽象为若干个筐,筐中有若干个球,每次从筐中取一个球,所有可能的球的组合。
    本质上是只取组合传统递归树最左边分支
  2. void f(map<数字,字母>,startIndex,[数字])
  3. if(ipath.size==数字个数){
    加入结果;
    return;
    }
  4. 回溯算法
    num【startIndex】;
    取出对应的字母;
    for(字母){
    加入ipath;
    f(map<数字,字母>,startIndex+1,[数字])
    回溯;
    }

代码

 StringBuilder sbPath = new StringBuilder();
    ArrayList<String> slistRes = new ArrayList<>();
    public List<String> letterCombinations(String digits) {
        if (digits==null||digits.length()==0){
            return slistRes;
        }
        String[] numString = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
        letterCombinationsBT(digits,numString,0);
        return slistRes;
    }

    public void letterCombinationsBT(String digits,String[] map,int startIndex) {
        // 出口
        if (sbPath.length()==digits.length()){
           slistRes.add(new String(sbPath));
           return;
       }
        // 回溯算法
        char c = digits.charAt(startIndex);
        String s = map[c - '0'];// 对应的字符组合
        // 内部回溯
        for (char c1 : s.toCharArray()) {
            sbPath.append(c1);
            // 下一层递归
            letterCombinationsBT(digits,map,startIndex+1); // 关键是startIndex+1
            // 回溯
            sbPath.delete(sbPath.length()-1,sbPath.length());
            // 进入本层下一层
        }
    }

复杂度

时间复杂度 0(数字个数*(3或4))
在这里插入图片描述

收获🐱‍🚀🐱‍🚀

1. 三刷在大脑过一遍
2. 本题通过画树竟然完美解决了
3. 若干袋子,求小球组合递归树
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/337958.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

为什么分库分表

系列文章目录 文章目录系列文章目录前言一、什么是分库分表二、分库分表的原因分库分表三、如何分库分表3.1 垂直拆分1.垂直分库2、垂直分表3.2 水平拆分水平分库水平分表水平分库分表的策略hash取模算法range范围rangehash取模混合地理位置分片预定义算法四、分库分表的问题分…

华为动态二进制翻译工具(ExaGear)

你还在为liunix x86程序移植到ARM环境而烦恼吗&#xff1f;你们现在您的福利来了&#xff0c;ExaGear可以解决您的烦恼&#xff0c;让您试下零代码迁移运行Linux x86程序。ExaGear是华为自研动态二进制翻译工具&#xff0c;通过在运行时&#xff0c;将x86应用指令翻译为ARM64指…

备战金三银四,软件测试面试题(全)

1.B/S架构和C/S架构区别 B/S 只需要有操作系统和浏览器就行&#xff0c;可以实现跨平台&#xff0c;客户端零维护&#xff0c;维护成本低&#xff0c;但是个性化能力低&#xff0c;响应速度较慢 C/S响应速度快&#xff0c;安全性强&#xff0c;一般应用于局域网中&#xff0c;因…

leetcode: Two Sum

leetcode: Two Sum1. 题目1.1 题目描述2. 解答2.1 baseline2.2 基于baseline的思考2.3 优化思路的实施2.3.1 C中的hashmap2.3.2 实施2.3.3 再思考2.3.4 最终实施3. 总结1. 题目 1.1 题目描述 Given an array of integers nums and an integer target, return indices of the …

Fluent Python 笔记 第 4 章 文本和字节序列

Python 3 明确区分了人类可读的文本字符串和原始的字节序列。隐式地把字节序列转换成 Unicode 文本已成过去。本章将要讨论 Unicode 字符串、二进制序列&#xff0c;以及在二者之间转 换时使用的编码。 没啥可看的&#xff0c;就一句话&#xff0c;一定不能依赖默认编码&#x…

DP优化 - 斜率优化

假设当前的 DP 方程为 fimin⁡0≤j<i{−K(i)X(j)Y(j)}F(i)f_i\min\limits_{0\leq j< i}\{-K(i)X(j)Y(j)\} F(i)fi​0≤j<imin​{−K(i)X(j)Y(j)}F(i) 或 fimax⁡0≤j<i{−K(i)X(j)Y(j)}F(i)f_i\max\limits_{0\leq j< i}\{-K(i)X(j)Y(j)\} F(i)fi​0≤j<im…

Node.js笔记-Express(基于Node.js的web开发框架)

目录 Express概述 Express安装 基本使用 创建服务器 编写请求接口 接收请求参数 获取路径参数(/login/2) 静态资源托管-express.static&#xff08;内置中间件&#xff09; 什么是静态资源托管&#xff1f; express.static() 应用举例 托管多个静态资源 挂载路径前缀…

车厢调度(train)(栈)

目录 题目描述 解题思路&#xff1a; 代码部分&#xff1a; 题目描述 有一个火车站&#xff0c;铁路如图所示&#xff0c;每辆火车从A驶入&#xff0c;再从B方向驶出&#xff0c;同时它的车厢可以重新组合。假设从A方向驶来的火车有n节&#xff08;n≤1000&#xff09;&…

Revit中关于屋顶编辑线移动的问题

一、Revit中关于屋顶编辑线移动的问题 在绘制屋顶的时候&#xff0c;如果出现有稍微偏差的时候&#xff0c;个别习惯移动编辑线&#xff0c;这种方法是不可取的&#xff0c;接下来为大家介绍一下这种方法的问题所在。 首先我们绘制几面这样的墙体&#xff0c;主要做测试用的&am…

锁升级之Synchronized

Synchronized JVM系统锁一个对象里如果有多个synchronized方法&#xff0c;同一时刻&#xff0c;只要有一个线程去调用其中的一个synchronized方法&#xff0c;其他线程只能等待&#xff01;锁的是当前对象&#xff0c;对象被锁定后&#xff0c;其他线程都不能访问当前对象的其…

流程引擎之发展史及对比总结

流程引擎渊源市场上比较有名的开源流程引擎有 jBPM、Activiti、Camunda、Flowable 和 Compileflow。其中 jBPM、Activiti、Flowable、camunda 四个框架同宗同源&#xff0c;祖先都是 jbpm4&#xff0c;开发者只要用过其中一个框架&#xff0c;基本上就会用其它三个。而 Compile…

SOFA Weekly|SOFANew、本周贡献 issue 精选

SOFA WEEKLY | 每周精选 筛选每周精华问答&#xff0c;同步开源进展欢迎留言互动&#xff5e;SOFAStack&#xff08;Scalable Open Financial Architecture Stack&#xff09;是蚂蚁集团自主研发的金融级云原生架构&#xff0c;包含了构建金融级云原生架构所需的各个组件&#…

基于Gromacs配体修饰自由能FPE计算(手动版)

基于Gromacs配体修饰自由能FPE计算(手动版) 本教程来自于https://github.com/huichenggong/Learning-Computation-with-Chenggong/tree/main/CC_news_008_ddG_uniFEP 我们将要使用的系统来自这篇论文 配体和受体pdb文件 A. 介绍 在本教程中&#xff0c;我们将使用非平衡自…

使用开源实时监控系统 HertzBeat 5分钟搞定 Mysql 数据库监控告警

使用开源实时监控系统 HertzBeat 对 Mysql 数据库监控告警实践&#xff0c;5分钟搞定&#xff01; Mysql 数据库介绍 MySQL是一个开源关系型数据库管理系统&#xff0c;由瑞典MySQL AB 公司开发&#xff0c;属于 Oracle 旗下产品。MySQL 是最流行的开源关系型数据库管理系统之…

VHDL语言基础-时序逻辑电路-锁存器

目录 锁存器的设计&#xff1a; RS锁存器&#xff1a; 真值表&#xff1a; 电路结构图&#xff1a; RS锁存器的仿真波形如下&#xff1a; D锁存器&#xff1a; D锁存器的仿真波形如下&#xff1a; 锁存器的设计&#xff1a; 为了与触发器相类比&#xff0c;我们先介绍锁…

奇舞周刊第 481 期 数据不够实时:试试长连接?

记得点击文章末尾的“ 阅读原文 ”查看哟~下面先一起看下本期周刊 摘要 吧~奇舞推荐■ ■ ■数据不够实时&#xff1a;试试长连接&#xff1f;在特定场景下&#xff0c;我们往往需要实时的去获取最新的数据&#xff0c;如获取消息推送或公告、股票大盘、聊天消息、实时的日志和…

面试(九)小米C++开发一面 21.11.02

1、局部变量与全局变量的区别?可以同名嘛? 首先是作用域: 局部变量只在变量声明的代码块范围内生效 全局变量在其声明后的所有位置都能访问到 在局部变量与全局变量同名的情况下,全局变量会被屏蔽掉,只会使用局部变量的内容 2、extern 当在a.c中想要使用b.c中的函数fu…

【Mac OS】JDK 多版本切换配置

前言 由于不同的项目可能需要使用的 JDK 版本不一样&#xff0c;所以在系统中配置多个 JDK 版本&#xff0c;并且能随时切换&#xff0c;是一个必要的配置。 查看已安装的 JDK 版本 /usr/libexec/java_home -V框框1是执行的命令 框框2是当前系统下所有的 JDK 版本 框框3是当…

1.7 Web学生管理系统

1.定义通讯协议基于前面介绍过的 FLask Web 网站 与 urlib 的访问网站的方法&#xff0c;设计一个综合应用实例。它是一个基于 Web 的学生记录管理程序。学生的记录包括 id(学号) 、name(姓名) 、grade(成绩)&#xff0c;服务器的作用是建立与维护一个Sqllite 的学生数据库 stu…

单目相机、双目相机和RGB-D相机学习笔记(一些视频和博文网址)

目录1. 单目相机1.1 摄像头原理1.2 单目相机的标定2 双目相机2.1 双目相机定位原理2.2 双目相机的缺陷3 RGB-D相机3.1 深度相机结构光原理3.2 RGB-D相机的应用1. 单目相机 1.1 摄像头原理 视频网址&#xff1a;【全网最详细】摄像头原理分析&#xff08;约25分钟课程&#xf…