图解力扣回溯及剪枝问题的模板应用

news2025/4/16 21:56:45

文章目录

  • 选哪个的问题
    • 17. 电话号码的字母组合
      • 题目描述
      • 解题代码
      • 图解
      • 复杂度
  • 选不选的问题
    • 78. 子集
      • 题目描述
      • 解题代码
      • 图解
      • 复杂度
  • 两相转化
    • 77. 组合
      • 题目描述
      • 解题代码
        • 法一:按选哪个的思路
        • 法二:按选不选的思路
      • 图解
        • 选哪个:
        • 选不选
      • 复杂度

选哪个的问题

17. 电话号码的字母组合

题目描述

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

img

示例 1:

输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]

示例 2:

输入:digits = ""
输出:[]

示例 3:

输入:digits = "2"
输出:["a","b","c"]

提示:

  • 0 <= digits.length <= 4
  • digits[i] 是范围 ['2', '9'] 的一个数字。

解题代码

class Solution {
    string MAPPING[10]= {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
public:
    vector<string> letterCombinations(string digits) {
        int n = digits.size();
        if(n == 0){
            return {};
        }
        vector<string> ans;
        string path(n, 0);
        auto dfs = [&](this auto&& dfs, int i){
            if(i == n){
                ans.push_back(path);
                return;
            }
            for(char c: MAPPING[digits[i] - '0']){
                path[i] = c;//元素覆盖
                dfs(i+1);
            }
        };
        dfs(0);
        return ans;

    }
};

图解

path存储每次得到的序列
核心代码:

for(char c: MAPPING[digits[i] - '0']){
	path[i] = c;
    dfs(i+1);
}

在这里插入图片描述

复杂度

时间复杂度:O(N*4^N)

注意,每次ans.push_back(path);也需要N的时间,所以前面乘N

空间复杂度:O(N*4^N)

ans 存储所有字母组合,共有 O(4^n) 个组合,递归存了n个点

选不选的问题

78. 子集

题目描述

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

示例 1:

输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]

示例 2:

输入:nums = [0]
输出:[[],[0]]

提示:

  • 1 <= nums.length <= 10
  • -10 <= nums[i] <= 10
  • nums 中的所有元素 互不相同

解题代码

class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        int n = nums.size();
        if(n == 0){
            return {};
        }
        vector<int> path;
        vector<vector<int>> ans;
        auto dfs = [&](this auto&& dfs, int i){
            if(i == n){
                ans.push_back(path);
                return;
            }
            dfs(i+1);//不选

            path.push_back(nums[i]);//选
            dfs(i+1);
            path.pop_back();//恢复现场
        };
        dfs(0);
        return ans;
    }
};

图解

在这里插入图片描述

选不选和排列问题有个区别是,如果某个数不被选择,空元素不能直接覆盖掉上一次递归中放在这个位置的元素,所以如果元素被选择,必须在递归结束后将该位置恢复到什么都没有的状态,也就是恢复现场,保证下一次递归不被影响。

复杂度

时间复杂度:O(N2^N)
空间复杂度:O(N
2^N)

两相转化

77. 组合

题目描述

给定两个整数 nk,返回范围 [1, n] 中所有可能的 k 个数的组合。

你可以按 任何顺序 返回答案。

示例 1:

输入:n = 4, k = 2
输出:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]

示例 2:

输入:n = 1, k = 1
输出:[[1]]

提示:

  • 1 <= n <= 20
  • 1 <= k <= n

解题代码

法一:按选哪个的思路
class Solution {
public:
    vector<vector<int>> combine(int n, int k) {
        vector<int> path;
        vector<vector<int>> ans;
        auto dfs = [&](this auto&& dfs, int i){
            int d = k - path.size();
            if(d == 0){ //取path长度合适的数组加入ans
                ans.push_back(path);
                return;
            }

            for(int j=i; j>=d; j--){
                path.push_back(j);
                dfs(j-1);
                path.pop_back();
            }
        };
        dfs(n);
        return ans;
    }
};
法二:按选不选的思路
class Solution {
public:
    vector<vector<int>> combine(int n, int k) {
        vector<int> path;
        vector<vector<int>> ans;
        auto dfs = [&](this auto&& dfs, int i){
            int d = k - path.size();
            if(d == 0){ //取path长度合适的数组加入ans
                ans.push_back(path);
                return;
            }

            if(i < d){
                return;
            }
            dfs(i-1);
            
            path.push_back(i);
            dfs(i-1);
            path.pop_back();
        };
        dfs(n);
        return ans;
    }
};

图解

选哪个:

在这里插入图片描述
这是剪枝后的情况,下面画一个正序、不引入d的没有剪枝的情况:
在这里插入图片描述
显然会冗余很多,代码也贴在这供大家参考:

class Solution {
public:
    vector<vector<int>> combine(int n, int k) {
        vector<int> path;
        vector<vector<int>> ans;
        auto dfs = [&](this auto&& dfs, int i){
        
            if(path.size() == k){ //取path长度合适的数组加入ans
                ans.push_back(path);
                return;
            }

            for(int j=i; j<=n; j++){
                path.push_back(j);
                dfs(j+1);
                path.pop_back();
            }
        };
        dfs(1);
        return ans;
    }
};
选不选

这种方法注意一点:只要不选,d就不会变,也就意味着两个节点如果是兄弟节点(父节点一样),那么他们的d相等,而一旦i < d,意味着这条线不可能出答案了,因为数字不够用,这个不只是剪枝,而且是必要的,不写会越界
在这里插入图片描述

复杂度

两个都是
时间复杂度:O(C(N,K)) (是排列组合的那个符号)
空间复杂度:O(N)


……可算画完了,好悬没给我累死

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

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

相关文章

Elasticsearch 8.X 如何利用嵌入向量提升搜索能力?

众所周知&#xff0c;Elasticsearch 是一个非常流行的搜索引擎&#xff0c;因为它速度快、扩展性强&#xff0c;尤其擅长全文搜索。 近两年&#xff0c;向量嵌入&#xff08;Vector Embedding&#xff09;技术的引入&#xff0c;让 Elasticsearch 在处理高级搜索场景时变得更强…

MySQL体系架构(一)

1.1.MySQL的分支与变种 MySQL变种有好几个,主要有三个久经考验的主流变种:Percona Server,MariaDB和 Drizzle。它们都有活跃的用户社区和一些商业支持,均由独立的服务供应商支持。同时还有几个优秀的开源关系数据库,值得我们了解一下。 1.1.1.Drizzle Drizzle是真正的M…

深度强化学习基础 0:通用学习方法

过去自己学习深度强化学习的痛点&#xff1a; 只能看到各种术语、数学公式勉强看懂&#xff0c;没有建立清晰且准确关联 多变量交互关系浮于表面&#xff0c;有时候连环境、代理控制的变量都混淆 模型种类繁多&#xff0c;概念繁杂难整合、对比或复用&#xff0c;无框架分析所…

虚幻5的C++调试踩坑

本地调试VS附加调试 踩坑1 预编译版本的UE5没有符号文件&#xff0c;无法调试源码 官方代码调试所需要的符号文件bdp需要下载导入。我安装的5.5.4是预编译版本&#xff0c;并非ue5源码。所以不含bdp文件。需要调试官方代码则需要通过EPIC中下载安装。右键UE版本&#xff0c;打…

通信协议详解(十):PSI5 —— 汽车安全传感器的“抗干扰狙击手”

一、PSI5是什么&#xff1f; 一句话秒懂 PSI5就像传感器界的“防弹信使”&#xff1a;在汽车安全系统&#xff08;如气囊&#xff09;中&#xff0c;用两根线同时完成供电数据传输&#xff0c;即便车祸时线路受损&#xff0c;仍能确保关键信号准确送达&#xff01; 基础概念…

从零开始学Python游戏编程18-函数3

《从零开始学Python游戏编程17-函数2》中&#xff0c;通过代码重构的方式将游戏的主要代码写入到自定义函数runGame()中。对于runGame()中的代码&#xff0c;可以继续对其进行重构&#xff0c;以达到简化代码结构的目的。 1 自定义函数askPlayer() 1.1 函数作用 自定义函数a…

Spring事务传播机制

Spring 事务传播机制定义了在多个事务方法相互调用时&#xff0c;事务如何在这些方法间传播。它决定了一个事务方法调用另一个事务方法时&#xff0c;新的事务是如何开启、是否要加入已有的事务等情况。Spring 提供了 7 种事务传播行为&#xff0c;下面是详细介绍。 解释说明&…

Java常用工具算法-5--哈希算法、加密算法、签名算法关系梳理

1、哈希算法 数学本质&#xff1a;将任意长度输入&#xff08;明文&#xff09;映射为固定长度输出&#xff08;哈希值&#xff0c;也称摘要&#xff09;。主要特点&#xff1a; 不可逆性&#xff1a;无法通过哈希值反推原始输入。雪崩效应&#xff1a;输入的微小变化导致哈希…

python之安装PaddlePaddle和PaddleX解析pdf表格

目录标题 飞桨PaddlePaddle本地安装教程1-1. 基于 Docker 安装飞桨1-2. 基于 pip 安装飞桨2. 我两个环境 都选择的是pip 安装10. 如果报错10. 离线安装 飞桨PaddlePaddle本地安装教程 源码下载&#xff1a;https://github.com/PaddlePaddle/PaddleX/blob/release/3.0-beta1/do…

【11408学习记录】英语语法核心突破:揭秘表语从句结构与通知写作实战技巧

表语从句与通知写作 英语语法总结——主从复合句表语从句语句结构系动词表语从句的位置 写作通知写作第二段第三段落款 每日一句词汇第一步&#xff1a;找谓语第二步&#xff1a;断句第三步&#xff1a;简化第一句第二句第三句第四句第五句 英语 语法总结——主从复合句 表语…

封装红黑树实现map和set

前言&#xff1a; 之前我们学习了set与map容器的如何使用&#xff0c;红黑树的实现。接下来我们来看看如何通过封装红黑树&#xff0c;实现我们自己的set与map 相关文章&#xff1a;oi&#xff01;让我来给你唠唠咋实现红黑树☝️-CSDN博客 超详细介绍map&…

解码AI大脑:Claude的思维显微镜与语言炼金术

&#xff08;前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff09;。 一、多语言思维实验&#xff1a;Claude的“概念空间”如何运转&#xff1f; 跨语言谜题&#xff1a;反义词的…

中科岩创基坑自动化监测解决方案

1.行业现状 城市基坑开挖具有施工风险高、施工难度大等特点。由于地下土体性质、荷载条件、施工环境的复杂性&#xff0c;单根据地质勘察资料和室内土工试验参数来确定设计和施工方案&#xff0c;往往含有许多不确定因素&#xff0c;对在施工过程中引发的土体性状、环境、邻近建…

机器学习01-支持向量机(SVM)(未完)

参考浙大 胡浩基老师 的课以及以下链接&#xff1a; https://blog.csdn.net/m0_74100344/article/details/139560508 https://blog.csdn.net/2301_78630677/article/details/132657023 https://blog.csdn.net/lsb2002/article/details/131338700 一、一些定义 T是倒置&…

[ctfshow web入门] web32

前置知识 协议相关博客&#xff1a;https://blog.csdn.net/m0_73353130/article/details/136212770 include&#xff1a;include "filename"这是最常用的方法&#xff0c;除此之外还可以 include url&#xff0c;被包含的文件会被当做代码执行。 data://&#xff1a…

鸿蒙开发中的并发与多线程

文章目录 前言异步并发 (Promise和async/await)多线程并发并发能力选择耗时任务并发执行场景常见业务场景 常驻任务并发执行场景常见业务场景 传统共享内存并发业务长时任务并发执行场景常见业务场景 并发任务管理线程间通信同语言线程间通信&#xff08;ArkTS内&#xff09;线…

TCP和UDP的区别是什么?

1. 基本特性: TCP&#xff1a; 面向连接&#xff1a;在数据传输开始前&#xff0c;TCP需要在通信双方建立连接&#xff08;三次握手&#xff09;。可靠性&#xff1a;TCP保证数据的可靠传输&#xff0c;通过确认应答、重传机制、数据包顺序等确保数据无误到达。流量控制和拥塞…

MySQL 函数(入门版)

目录 一、字符串函数 1、常用的字符串函数 2、函数演示 3、具体案例 二、数值函数 1、常用的数值函数 2、函数演示 3、具体案例 三、日期函数 1、常用的日期函数 2、函数演示 3、具体案例 四、流程函数 1、常用的流程函数 2、函数演示 3、具体案例 在MySQL中&a…

Simulink中Signal Builder在新版中找不到怎么办

在较新的MATLAB版本中&#xff0c;新版Simulink中的Signal Builder用Signal Editor作为替代工具。 signal builder not shown in matlab - MATLAB Answers - MATLAB Central signalBuilderToSignalEditor 1.打开上面第二个链接 2.点击拷贝 3.然后在命令行中粘贴 4.然后就会…

SvelteKit 最新中文文档教程(19)—— 最佳实践之身份认证

前言 Svelte&#xff0c;一个语法简洁、入门容易&#xff0c;面向未来的前端框架。 从 Svelte 诞生之初&#xff0c;就备受开发者的喜爱&#xff0c;根据统计&#xff0c;从 2019 年到 2024 年&#xff0c;连续 6 年一直是开发者最感兴趣的前端框架 No.1&#xff1a; Svelte …