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

算法学习——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;
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Leetcode 606.根据二叉树创建字符串

给你二叉树的根节点root&#xff0c;请你采用前序遍历的方式&#xff0c;将二叉树转化为一个由括号和整数组成的字符串&#xff0c;返回构造出的字符串。 空节点使用一对空括号对"root"表示&#xff0c;转化后需要省略所有不影响字符串与原始二叉树之间的一对一映射…

openGauss学习笔记-219 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-网络

文章目录 openGauss学习笔记-219 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-网络219.1 查看网络状况 openGauss学习笔记-219 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-网络 获取openGauss节点的CPU、内存、I/O和网络资源使用情况&#xff0c;确认这些资源…

在Meteor Lake平台上使用NPU进行AI推理加速

在Meteor Lake平台上&#xff0c;英特尔通过神经处理单元 (NPU) 将人工智能直接融入芯片中&#xff0c;实现桌面电脑平台的AI推理功能。神经处理单元 (NPU) 是一种专用人工智能引擎&#xff0c;专为运行持续的人工智能推理工作负载而设计。与即将推出的支持深度人工智能集成的 …

【MySQL】索引事务

MySQL索引事务 1. 索引1.1 概念1.2 作用1.3 使用场景1.4 使用1.5 案例 2. 事务2.2 事物的概念2.3 使用 3. 内容重点总结 1. 索引 1.1 概念 索引是一种特殊的文件&#xff0c;包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引&#xff0c; 并指定索引的类…

ClickHouse--04--数据库引擎、Log 系列表引擎、 Special 系列表引擎

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.数据库引擎1.1 Ordinary 默认数据库引擎1.2 MySQL 数据库引擎MySQL 引擎语法字段类型的映射 2.ClickHouse 表引擎3.Log 系列表引擎几种 Log 表引擎的共性是&#…

Golang快速入门到实践学习笔记

Go学习笔记 1.基础 Go程序设计的一些规则 Go之所以会那么简洁&#xff0c;是因为它有一些默认的行为&#xff1a; 大写字母开头的变量是可导出的&#xff0c;也就是其它包可以读取 的&#xff0c;是公用变量&#xff1b;小写字母开头的就是不可导出的&#xff0c;是私有变量…

Python算法题集_二叉树的最大深度

Python算法题集_二叉树的最大深度 题104&#xff1a;二叉树的最大深度1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【DFS自顶向下】2) 改进版一【DFS自底向上】3) 改进版二【BFS】 4. 最优算法 本文为Python算法题集之一的代码示例 题104&am…

现代化端口扫描工具RustScan

今天是大年初五&#xff0c;喜迎财神 &#xff0c;祝大家✔️顺风顺水 ✔️诸事如意 ✔️财源滚滚 ✔️大吉大利 顺便提一下&#xff0c;老苏的博客启用了新域名&#xff1a; https://laosu.tech 什么是 RustScan &#xff1f; RustScan 是一款现代化的端口扫描器。能快速找到端…

数学实验第三版(主编:李继成 赵小艳)课后练习答案(九)(1)(2)

实验九&#xff1a;线性函数极值求解 练习一 1.求解线性规划问题&#xff1a; &#xff08;1&#xff09;max z3,s.t. clc;clear; %采用软件解法 c[-3,-1]; a[-1,1;1,-2;3,2]; b[2;2;14]; [x,min]linprog(c,a,b)找到最优解。 x 4 1 min -13 题上要求的是最大值&#…

【从零到Offer】MySQL最左匹配

前言 ​ 相信大家在日常开发时&#xff0c;也经常能听到“最左匹配”这个词&#xff0c;那么什么是最左匹配呢&#xff1f;本篇文章就带你一起探索“最左匹配”的神奇秘密。 什么是最左匹配 ​ 最左匹配&#xff0c;通常指的是最左前缀匹配原则&#xff0c;即MySQL在检索数据…

c++ Qt 数据库操作

1、准备工作 Qt本身并没有数据库功能&#xff0c;但是Qt支持调用其他主流的数据库产品&#xff0c;并且这些数据库产品统一了Qt的接口&#xff0c;实际上是一种数据库的中间件。 Qt支持以下数据库类型&#xff1a; 嵌入式常用的数据库是sqlite3&#xff0c;本体只有几兆大小。非…

UnityShader玉石效果

效果&#xff1a; 代码&#xff1a; Shader "MyShader/Jade" {Properties{_DiffuseColor("漫反射颜色",color)(1,1,1,1)_ThicknessMap("厚度图",2d)"white"{}_AddColor("叠加颜色",color)(1,1,1,1)_CubeMap("环境贴图…

java实现多级目录树(递归实现)

一.应用场景 有时候需要我们后台给前台传树结构的数据&#xff0c;要怎么查询? 怎么返回数据呢&#xff1f; 二.数据库表设计以及数据内容(以部门举例) id 主键 parent_id 父级部门id depart_name 部门名词 sort 部门排序三.实体类 Data public…

Qt 软件封装与打包

1. Qt 软件封装 1、首先以 release 方式进行编译&#xff0c;将生成的 CloudOne.exe 文件复制到 D:\CloudApp 文件夹&#xff08;自行创建&#xff09; 2、打开 Qt 命令行工具&#xff08;如下图所示&#xff09;&#xff0c;并按顺序输入如下指令 cd D:\CloudApp windeployq…

Spring Boot 笔记 019 创建接口_文件上传

1.1 创建阿里OSS bucket OSS Java SDK 兼容性和示例代码_对象存储(OSS)-阿里云帮助中心 (aliyun.com) 1.2 编写工具类 package com.geji.utils;import com.aliyun.oss.ClientException; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun…

每日一题——数字翻转

题目; 这道题看似是很简单的回文数 实则就是很简单的回文数 但是需要注意的一点是负数 可以在开头就进行判断&#xff0c;如果N<0的话就令N-N&#xff0c;将所有数都转成正数就好办了 上代码&#xff1a; #include <iostream> #include<string> #include<…

算法沉淀——哈希算法(leetcode真题剖析)

算法沉淀——哈希算法 01.两数之和02.判定是否互为字符重排03.存在重复元素04.存在重复元素 II05.字母异位词分组 哈希算法&#xff08;Hash Algorithm&#xff09;是一种将任意长度的输入&#xff08;也称为消息&#xff09;映射为固定长度的输出的算法。这个输出通常称为哈希…

Spring Security学习(四)——登陆认证(包括自定义登录页)

前言 和前面的文章隔了很长时间才更新Spring Security系列&#xff0c;主要原因一个是之前太忙了&#xff0c;把项目都忙完了&#xff0c;赶上春节假期&#xff0c;就慢慢研究。Spring Security的体系非常复杂&#xff0c;一口吃不了热豆腐&#xff0c;没办法速成&#xff0c;…

微服务—ES数据同步

目录 数据同步 问题分析 方案1. 同步调用 方案2. 异步通知 方案3. 监听binlog​编辑 各方案对比 案例——利用MQ实现数据同步 步骤1. 导入hotel-admin项目 步骤2. 声明交换机、队列 步骤3. 发送MQ消息 步骤4. 接收MQ消息 步骤5. 测试同步功能 数据同步 elasticsea…

八、键盘响应

之前博文格式已经固定&#xff0c;这里就不在赘述了&#xff0c;直接把核心代码进行解释一下即可&#xff0c;仅作为小笔记而已 项目实现功能&#xff1a; 按下键盘0&#xff0c;显示原始图像 按下键盘1&#xff0c;显示原始图像的灰度图 按下键盘2&#xff0c;显示原始图像的…