算法学习——LeetCode力扣回溯篇1

news2024/11/29 2:43:52

算法学习——LeetCode力扣回溯篇1

在这里插入图片描述

77. 组合

77. 组合 - 力扣(LeetCode)

描述

任何顺序 返回答案。

示例

示例 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>> result;
    vector<int> path;
    //left是for的开始 ,right是for的结束。当size==k的时候递归结束
    void tarversal(int left , int right , int k)
    {
        if(path.size() == k)
        {
            result.push_back(path);
            return;
        }else
        {
            for(int i= left ; i <= right ; i++)
            {
                path.push_back(i);
                tarversal(i+1 ,right , k);
                path.pop_back();
            }
            return;
        }
       
    }
    vector<vector<int>> combine(int n, int k) {
        tarversal(1,n,k);
        return result;
    }
};

回溯剪枝法

剪枝是减少无意义循环的过程
在这里插入图片描述

当输入是n=4,k=4的时候,只有1234符合。我们遍历到2开始时,最多为234,234的长度为3满足长度为4的情况,是无意义的,要剪去。

for(int i= left ; i <= right - (k - path.size()) +1 ; i++) 为剪枝的判断

其中left为遍历的开始,right为遍历的结束。现在还需要找到k - path.size()个点
即 right - left => (k - path.size()) ,为剩下的点可以满足k的要求
=>left <= right - (k - path.size()) +1 , 其中+1为满足左边闭合。
例,k=3,n=4时,已经选取的为0个(path.size()=0),带入i <= right - ( k - path.size() ) +1 , i <= 4 - (3-0)+1 ,为i<=2。
即当i最大为从2开始满足,为234 。大于2 剪枝

class Solution {
public:
    vector<vector<int>> result;
    vector<int> path;
    void tarversal(int left , int right , int k)
    {
        if(path.size() == k)
        {
            result.push_back(path);
            return;
        }else
        {
           //i <= right - (k - path.size()) +1为剪枝的过程,避免无意义的循环
            for(int i= left ; i <= right - (k - path.size()) +1 ; i++)
            {
                path.push_back(i);
                tarversal(i+1 ,right , k);
                path.pop_back();
            }
            return;
        }
       
    }
    vector<vector<int>> combine(int n, int k) {
        tarversal(1,n,k);
        return result;
    }
};

216. 组合总和 III

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

描述

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

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

示例

示例 1:

输入: k = 3, n = 7
输出: [[1,2,4]]
解释:
1 + 2 + 4 = 7
没有其他符合的组合了。

示例 2:

输入: k = 3, n = 9
输出: [[1,2,6], [1,3,5], [2,3,4]]
解释:
1 + 2 + 6 = 9
1 + 3 + 5 = 9
2 + 3 + 4 = 9
没有其他符合的组合了。

示例 3:

输入: k = 4, n = 1
输出: []
解释: 不存在有效的组合。
在[1,9]范围内使用4个不同的数字,我们可以得到的最小和是1+2+3+4 = 10,因为10 > 1,没有有效的组合。

提示

  • 2 <= k <= 9
  • 1 <= n <= 60

代码解析

回溯法无减枝
class Solution {
public:
    vector<vector<int>> result;
    vector<int> path;

    void backtraking(int k, int n , int sum ,int startidx)
    {
        if(path.size() == k && sum == n)
        {
            result.push_back(path);
            return;
        }else
        {
            for(int i= startidx ; i < 10 ; i++)
            {
                path.push_back(i);
                backtraking(k,n,sum+i,i+1);
                path.pop_back();
            }
            return;
        }
    }
    vector<vector<int>> combinationSum3(int k, int n) {
        backtraking(k,n,0,1);
        return result;
    }
};

回溯剪枝

剪枝原理同 77题

class Solution {
public:
    vector<vector<int>> result;
    vector<int> path;

    void backtraking(int k, int n , int sum ,int startidx)
    {
        if(sum > n) return;
        if(path.size() == k && sum == n)
        {
            result.push_back(path);
            return;
        }else
        {
            for(int i= startidx ; i < 10 - (k - path.size()) + 1 ; i++)
            {
                path.push_back(i);
                backtraking(k,n,sum+i,i+1);
                path.pop_back();
            }
            return;
        }
    }
    vector<vector<int>> combinationSum3(int k, int n) {
        backtraking(k,n,0,1);
        return result;
    }
};

17. 电话号码的字母组合

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

描述

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

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

示例

示例 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 {
public:
    const string letterMap[10] = {
        "", // 0
        "", // 1
        "abc", // 2
        "def", // 3
        "ghi", // 4
        "jkl", // 5
        "mno", // 6
        "pqrs", // 7
        "tuv", // 8
        "wxyz", // 9
    };
    
    vector<string> result;
    //输入参:转换后的vector , 从第几个按键开始循环 , 已经走的路径
    void backtarcking(vector<int> &digits_i , int startidx , string path)
    { 	
    	//当路径的长度等于数组的长度,存入结果
        if(path.size() == digits_i.size() )
        {
            result.push_back(path);
            return;
        }
        else
        {	
        	//第一次循环,循环数字
            for(int i = startidx ; i < digits_i.size() ; i++)
            {
            	//找到输入数字对应的字母表
                string tmp = letterMap[digits_i[i]];
                vector<char> tmp_v(tmp.begin() , tmp.end()) ;
                //第二次循环,循环每一个数字的字母
                for(int j=0 ; j < tmp_v.size() ; j++)
                {
                	//递归回溯,开始循环的数字往后走一个,路径加上已经走的路径
                    backtarcking(digits_i, i+1 , path + tmp_v[j]);
                }
            }
            return;
        }
         return;
    }
    vector<string> letterCombinations(string digits) {
		//输入为空时直接返回
        if(digits.size()==0) return result;
		//字符串转换成vector
        vector<int> digits_i;
        for(auto i:digits) digits_i.push_back( i - '0' );
       
        string path;
        backtarcking(digits_i , 0 , path);

        return result;
    }
};

map表
class Solution {
public:
    vector<string> result;
    string worldPath;
    map<char,vector<string>> myMap;
    void map_init()
    {
        myMap.insert(pair<char,vector<string>>('2',{"a","b","c"})) ;
        myMap.insert(pair<char,vector<string>>('3',{"d","e","f"})) ;
        myMap.insert(pair<char,vector<string>>('4',{"g","h","i"})) ;
        myMap.insert(pair<char,vector<string>>('5',{"j","k","l"})) ;
        myMap.insert(pair<char,vector<string>>('6',{"m","n","o"})) ;
        myMap.insert(pair<char,vector<string>>('7',{"p","q","r","s"})) ;
        myMap.insert(pair<char,vector<string>>('8',{"t","u","v"})) ;
        myMap.insert(pair<char,vector<string>>('9',{"w","x","y","z"})) ;
        // for(auto it:myMap)
        //      cout<<it.first<<':'<<(it.second)[0]<<endl;
        // cout<<myMap['2'].size();
    }
    void dfs(string digits , int fir )
    {
        
        if( worldPath.size() == digits.size())
        {
            result.push_back(worldPath);
            return;
        }

        char num = digits[fir];
        for(int j=0 ; j< myMap[num].size() ;j++)
        {
            worldPath += myMap[num][j];
            dfs(digits,fir+1);
            worldPath.pop_back();
        }
        
        return;
    }
    vector<string> letterCombinations(string digits) {
        if(digits.size()==0) return result;
        map_init();
        dfs(digits,0);
        return result;
    }
};

39. 组合总和

39. 组合总和 - 力扣(LeetCode)

描述

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。

对于给定的输入,保证和为 target 的不同组合数少于 150 个。

示例

示例 1:

输入:candidates = [2,3,6,7], target = 7
输出:[[2,2,3],[7]]
解释:
2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。
7 也是一个候选, 7 = 7 。
仅有这两种组合。

示例 2:

输入: candidates = [2,3,5], target = 8
输出: [[2,2,2,2],[2,3,3],[3,5]]

示例 3:

输入: candidates = [2], target = 1
输出: []

提示

  • 1 <= candidates.length <= 30
  • 2 <= candidates[i] <= 40
  • candidates 的所有元素 互不相同
  • 1 <= target <= 40

代码解析

暴力回溯(无剪枝,时间复杂度高)
class Solution {
public:
    vector<vector<int>> result;
    vector<int> path;
    int sum;
    void backtracking(vector<int>& candidates, int target , int sum)
    {	
    	//检测目标大于时返回
        if(sum > target) return;
        if(sum == target)
        {
        	//排序后发现是新结果插入
            vector<int> tmp(path.begin(),path.end());
            sort(tmp.begin(),tmp.end());
            auto it = find(result.begin(),result.end(),tmp);
            if(it == result.end()) result.push_back(tmp);
            return;
        }
		//无任何限制回溯
        for(int i = 0 ; i < candidates.size() ;i++)
        {
            path.push_back(candidates[i]);
            backtracking(candidates,target,sum+candidates[i]);
            path.pop_back();
        }
        return;
    }
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
      
        backtracking(candidates,target,0);
        return result;
    }
};


回溯剪枝
class Solution {
public:
    vector<vector<int>> result;
    vector<int> path;
    int sum;
    void backtracking(vector<int>& candidates, int target , int sum , int indnx)
    {
        if(sum > target) return;
        if(sum == target)
        {
            result.push_back(path);
            return;
        }
  		//剪枝,因为之前已经对输入进行排序,当发现加上i点的值大于目标后,后面的也都大于
        for(int i = indnx ; i < candidates.size() && sum+candidates[i] <= target ;i++)
        {
            path.push_back(candidates[i]);
            //递归的下一个指针和当前一样都是i,不是i+1 
            //因为一个数可以重复的使用,不能重复是i+1
            backtracking(candidates,target,sum+candidates[i] , i);
            path.pop_back();
        }
        return;
    }
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        //对输入进行排序,方便后面循环
        sort(candidates.begin(),candidates.end());
        backtracking(candidates,target,0,0);
        return result;
    }
};

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

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

相关文章

springboot743二手交易平台

springboot743二手交易平台 获取源码——》公主号&#xff1a;计算机专业毕设大全

《Java 简易速速上手小册》第8章:Java 性能优化(2024 最新版)

文章目录 8.1 性能评估工具 - 你的性能探测仪8.1.1 基础知识8.1.2 重点案例&#xff1a;使用 VisualVM 监控应用性能8.1.3 拓展案例 1&#xff1a;使用 JProfiler 分析内存泄漏8.1.4 拓展案例 2&#xff1a;使用 Gatling 进行 Web 应用压力测试 8.2 JVM 调优 - 魔法引擎的调校8…

第四篇【传奇开心果微博系列】Python微项目技术点案例示例:美女颜值判官

传奇开心果微博系列 系列微博目录Python微项目技术点案例示例系列 微博目录一、微项目目标二、雏形示例代码三、扩展思路四、添加不同类型的美女示例代码五、增加难度等级示例代码六、添加特殊道具示例代码七、设计关卡系统示例代码八、添加音效和背景音乐示例代码九、多人游戏…

【解决】idea控制台不输出trace/debug日志

idea控制台不输出trace日志 问题原因解决 问题 idea控制台不输出trace日志。 pom文件&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></dependency>输出lo…

23种计模式之Python/Go实现

目录 设计模式what?why?设计模式&#xff1a;设计模式也衍生出了很多的新的种类&#xff0c;不局限于这23种创建类设计模式&#xff08;5种&#xff09;结构类设计模式&#xff08;7种&#xff09;行为类设计模式&#xff08;11种&#xff09; 六大设计原则开闭原则里氏替换原…

P3612 [USACO17JAN] Secret Cow Code S题解

题目 奶牛正在试验秘密代码&#xff0c;并设计了一种方法来创建一个无限长的字符串作为其代码的一部分使用。 给定一个字符串&#xff0c;让后面的字符旋转一次&#xff08;每一次正确的旋转&#xff0c;最后一个字符都会成为新的第一个字符&#xff09;。也就是说&#xff0…

localStorage、sessionStorage、cookie区别

localStorage: localStorage 的生命周期是永久的&#xff0c;关闭页面或浏览器之后 localStorage 中的数据也不会消失。localStorage 除非主动删除数据&#xff0c;否则数据永远不会消失 sessionStorage: sessionStorage 的生命周期是仅在当前会话下有效。sessionStorage 引入…

【STM32 CubeMX】STM32中断体系结构

文章目录 前言一、中断体系的比喻二、中断的内部结构2.1 EXTI触发方式 2.2 NVIC2.3 cpu与中断2.4 外部中断控制器框图上升沿触发选择寄存器屏蔽/使能寄存器等待处理寄存器 2.5 中断优先级 总结 前言 一、中断体系的比喻 STM32中断体系如下图所示&#xff1a; 一座大型建筑物…

(二)【Jmeter】专栏实战项目靶场drupal部署

该专栏后续实战示例&#xff0c;都以该篇部署的项目展开操作。 前置条件 参考“&#xff08;一&#xff09;【Jmeter】JDK及Jmeter的安装部署及简单配置” 安装部署Jmeter&#xff0c;从文章最后下载“Postman、Rancher.ova、VirtualBox-7.0.12-159484-Win.exe、Xshell-7.0.01…

VUE学习——表单的输入绑定

使用【v-model】。 输入框 <template><h1>表单输入绑定</h1><input type"text" v-model"message"><p>输入的值&#xff1a;{{ message }}</p> </template> <script>export default{data(){return{messa…

java 数据结构ArrayList类

目录 什么是List 线性表 顺序表 ArrayList类 ArrayList无参方法 ArrayList有参方法 &#xff1f;通配符 ArrayList 的remove方法 ArrayList 的subList方法 Iterator&#xff1a;迭代器 使用ArrayList完成杨辉三角 什么是List 在集合框架中&#xff0c;List是一个接…

FileZilla Server 1.8.1内网搭建

配置环境服务器服务器下载服务器配置服务器配置 Server - ConfigureServer Listeners - Port 协议设置 Protocols settingsFTP and FTP over TLS(FTPS) Rights management(权利管理)Users(用户) 客户端建立连接 配置环境 服务器处于局域网内: 客户端 < -访问- > 公网 &l…

猫头虎分享已解决Bug || Invariant Violation in React: Element Type is Invalid ‍

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

HarmonyOS鸿蒙学习基础篇 - 自定义组件(一)

前言 在ArkUI中&#xff0c;UI显示的内容均为组件&#xff0c;由框架直接提供的称为系统组件&#xff0c;由开发者定义的称为自定义组件。在进行 UI 界面开发时&#xff0c;通常不是简单的将系统组件进行组合使用&#xff0c;而是需要考虑代码可复用性、业务逻辑与UI分离&#…

987. 二叉树的垂序遍历 - 力扣(LeetCode)

题目描述 给你二叉树的根结点 root &#xff0c;请你设计算法计算二叉树的 垂序遍历 序列。 对位于 (row, col) 的每个结点而言&#xff0c;其左右子结点分别位于 (row 1, col - 1) 和 (row 1, col 1) 。树的根结点位于 (0, 0) 。 二叉树的 垂序遍历 从最左边的列开始直到…

代码随想录算法训练营第46天|198.打家劫舍、213.打家劫舍II、337.打家劫舍III

文章目录 198.打家劫舍思路代码 213.打家劫舍II思路代码 337.打家劫舍III思路代码 198.打家劫舍 题目链接&#xff1a;198.打家劫舍 文章讲解&#xff1a;代码随想录|198.打家劫舍 思路 1.dp[i]:从0打劫到i所获得的最高金额 2.是否打劫第i个决定了dp[i]&#xff1a;如果打劫则…

Unity类银河恶魔城学习记录7-4 P70 Improving sword‘s behaviour源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili Sword_Skill_Controller.cs using System.Collections; using System.Colle…

浅谈Linux环境

冯诺依曼体系结构&#xff1a; 绝大多数的计算机都遵守冯诺依曼体系结构 在冯诺依曼体系结构下各个硬件相互配合处理数据并反馈结果给用户 其中控制器和运算器统称为中央处理器&#xff08;CPU&#xff09;&#xff0c;是计算机硬件中最核心的部分&#xff0c;像人类的大脑操控…

【记录】记一次关于前端单元测试的全英文问卷调查( Survey: Automatically Generated Test Suites for JavaScript)

文章目录 OPENING STATEMENTBackgroundTask background: Fix the failing test casesBefore the task: Task: Fix the failing test casesTask: Executable DocumentationBefore the task: Bonus Opportunity: One more taskTask: Test Cases ClusteringRewardThank You! 原地址…

RocketMQ与Kafka架构深度对比

在分布式系统中&#xff0c;消息中间件扮演着至关重要的角色&#xff0c;它们负责在系统组件之间传递消息&#xff0c;实现解耦、异步通信和流量削峰等功能。RocketMQ与Kafka作为两款流行的消息中间件&#xff0c;各自拥有独特的架构设计和功能特性。本文将深入对比分析RocketM…