24暑假算法刷题 | Day22 | LeetCode 77. 组合,216. 组合总和 III,17. 电话号码的字母组合

news2024/12/24 18:14:36

目录

  • 77. 组合
    • 题目描述
    • 题解
  • 216. 组合总和 III
    • 题目描述
    • 题解
  • 17. 电话号码的字母组合
    • 题目描述
    • 题解


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

题解

参考:代码随想录-77.组合 ,讲得非常细了。

算是回溯算法的入门题目,核心要理解回溯的树形结构,以及其中的横向纵向遍历逻辑:

img

然后,考虑回溯三部曲

1️⃣ 处理

本题就是很基础的求组合,所以每次往当前组合 path 添加新数字就好了:

path.push_back(i); 

当前组合名称取为 path ,旨在呼应回溯树形结构图中的纵向“探索”路线(先取一个数x,再取一个数y)

2️⃣ 递归

递归出口是经典的——当前组合大小达到目标组合大小,则将其加入结果集:

if (path.size() == k)
{
    res.push_back(path);
    return;
}

否则,当前位置数字确定后,递归下一个位置的数来做组合:

backTracking(i + 1, end, k)

3️⃣ 回溯

弹出当前组合的最后一个值,以便探索该位置的其他可能值:

path.pop_back();   

整体代码如下:

C++

class Solution
{
private:
    vector<int> path;
    vector<vector<int>> res;

public:
    void backTracking(int start, int end, int k)
    {
        // 回溯出口:子结果path已满(纵向遍历)
        if (path.size() == k)
        {
            res.push_back(path);
            return;
        }
        // 横向遍历
        for (int i = start; i <= end; i++)
        {
            path.push_back(i);           // 处理
            backTracking(i + 1, end, k); // 递归
            path.pop_back();             // 回溯
        }
    }

    vector<vector<int>> combine(int n, int k)
    {
        backTracking(1, n, k);
        return res;
    }
};

Go

type Helper struct {
	path []int
	res  [][]int
}

func (helper *Helper) backTracking(start int, end int, k int) {
	// 递归出口
	if len(helper.path) == k {
		// newPath := make([]int, len(helper.path))
		// copy(newPath, helper.path)
		// helper.res = append(helper.res, newPath)
		helper.res = append(helper.res, append([]int(nil), helper.path...))
		return
	}
	// 横向遍历
	for i := start; i <= end; i++ {
		helper.path = append(helper.path, i)           // 处理
		helper.backTracking(i+1, end, k)               // 递归
		helper.path = helper.path[:len(helper.path)-1] // 回溯
	}
}

func combine(n int, k int) [][]int {
	helper := Helper{}
	helper.backTracking(1, n, k)
	return helper.res
}

216. 组合总和 III

点此跳转题目链接

题目描述

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

  • 只使用数字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

题解

参考:代码随想录-216

回溯算法解决。首先想清楚回溯的树形结构图:

在这里插入图片描述

然后走回溯三部曲

  • 处理: 将当前处理的数字加入当前组合 path ,并求此时组合中的数字和

    进行这一步之前可以剪枝:由于是从1到9(从小到大)横向遍历,如果 目标和 与 当前和 的差小于即将加入的数字,说明再加数字必将导致组合总和过大,故没必要在此基础上往后遍历处理了。

  • 递归: 递归地尝试将后面的数字加入组合;递归出口: path 的大小达到目标大小 k ,且其中数字和等于目标和,则将 path 加入结果集

  • 回溯: 弹出当前组合的最后一个数,以便探索该位置放其他数的可能

代码如下:

class Solution
{
private:
    vector<int> path;
    vector<vector<int>> res;

public:
    void backTracking(int start, int end, int maxPathSize, int targetSum, int curSum)
    {
        // 递归出口(纵向遍历)
        if (path.size() == maxPathSize)
        {
            if (curSum == targetSum)
                res.push_back(path);
            return;
        }
        // 剪枝
        if (targetSum - curSum < start)
            return;
        // 横向遍历
        for (int i = start; i <= end; i++)
        {
            curSum += i;
            path.push_back(i);                                        // 处理
            backTracking(i + 1, end, maxPathSize, targetSum, curSum); // 递归
            curSum -= i;
            path.pop_back(); // 回溯
        }
    }

    vector<vector<int>> combinationSum3(int k, int n)
    {
        backTracking(1, 9, k, n, 0);
        return res;
    }
};

17. 电话号码的字母组合

点此跳转题目链接

题目描述

给定一个仅包含数字 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'] 的一个数字。

题解

参考:代码随想录-17

回溯算法解决。首先想清楚回溯的树形结构图:

在这里插入图片描述

然后走回溯三部曲

  • 处理: 从当前处理的数字对应的字母串中,取一个字母加入当前组合(字符串) path

  • 递归: 递归地尝试将后面的数字对应的可能字母加入组合;递归出口: path 的长度与所给数字串 digits 相同,则将 path 加入结果集

  • 回溯: 弹出当前组合的最后一个字符,以便探索该位置放其他字母的可能

c++代码如下:

class Solution
{
private:
    string path = "";
    vector<string> res;
    unordered_map<char, string> dict = {
        {'2', "abc"},
        {'3', "def"},
        {'4', "ghi"},
        {'5', "jkl"},
        {'6', "mno"},
        {'7', "pqrs"},
        {'8', "tuv"},
        {'9', "wxyz"}};

public:
    void backTracking(const string &digits, int start)
    {
        // 递归出口
        if (path.length() == digits.length())
        {
            res.push_back(path);
            return;
        }
        char digit = digits[start];   // 当前要处理的数字
        string letters = dict[digit]; // 当前处理数字对应的字母
        // 横向遍历
        for (int i = 0; i < letters.length(); i++)
        {
            path.push_back(letters[i]);      // 处理
            backTracking(digits, start + 1); // 递归
            path.pop_back();                 // 回溯
        }
    }
    vector<string> letterCombinations(string digits)
    {
        if (digits == "")
            return res;
        backTracking(digits, 0);
        return res;
    }
};

顺便再熟悉下golang:

type Helper struct {
	path string
	res  []string
	dict map[byte]string
}

func newHelper() *Helper {
	return &Helper{
		dict: map[byte]string{
			'2': "abc",
			'3': "def",
			'4': "ghi",
			'5': "jkl",
			'6': "mno",
			'7': "pqrs",
			'8': "tuv",
			'9': "wxyz",
		},
	}
}

func (helper *Helper) backTracking(digits string, start int) {
	// 递归出口
	if len(helper.path) == len(digits) {
		helper.res = append(helper.res, helper.path)
		return
	}
	letters := helper.dict[digits[start]]
	for _, letter := range letters {
		helper.path = helper.path + string(letter)     // 处理
		helper.backTracking(digits, start+1)           // 递归
		helper.path = helper.path[:len(helper.path)-1] // 回溯
	}
}

func letterCombinations(digits string) []string {
	helper := newHelper()
	if len(digits) == 0 {
		return helper.res
	}
	helper.backTracking(digits, 0)
	return helper.res
}

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

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

相关文章

python爬虫入门小案例

python爬虫 以下内容仅供学习交流,请勿用作其他用途,若涉及隐私和版权问题,请及时联系我删除 闲来无事,学了学爬虫小知识,适合入门,文笔拙劣,还望见谅 爬虫是什么: 爬取网页上的文字,图片,视频,音频 自动化操作浏览器,比如填写表单,打卡,提高工作效率爬虫的注意事项: 爬虫…

lua 游戏架构 之 游戏 AI (九)ai_mgr Ai管理

定义ai_mgr的类&#xff0c;用于管理游戏中实体的AI组件。 先定义 AI行为枚举和优先级&#xff1a; lua 游戏架构 之 游戏 AI &#xff08;八&#xff09;ai_tbl 行为和优先级-CSDN博客https://blog.csdn.net/heyuchang666/article/details/140712839?spm1001.2014.3001.55…

MySQL环境的配置文件json

突然了解到&#xff0c;使用json文件去进行环境的配置&#xff0c;这样修改参数的时候就只需要去改json文件中的内容&#xff0c;不需要去修改代码中的内容&#xff0c;其他人的MySQL和我的MySQL也不同&#xff0c;这时其他人只需要修改json文件中的内容&#xff0c;清晰明了&a…

基于微信小程序+SpringBoot+Vue的核酸检测服务系统(带1w+文档)

基于微信小程序SpringBootVue的核酸检测服务系统(带1w文档) 基于微信小程序SpringBootVue的核酸检测服务系统(带1w文档) 在目前的情况下&#xff0c;可以引进一款医院核酸检测服务系统这样的现代化管理工具&#xff0c;这个工具就是解决上述问题的最好的解决方案。它不仅可以实…

2024年开发者最爱用的Bug跟踪工具

国内外主流的10款BUG管理软件对比&#xff1a;PingCode、Worktile、禅道&#xff08;ZenTao&#xff09;、Bugzilla、Tapd、CODING、Teambition、Testin、Tower、乐道。 在软件开发的世界里&#xff0c;管理和跟踪Bug是一个让许多开发者头疼的问题。选择一个合适的Bug管理工具不…

C++题目_逃生路线总数(dfs)

题目描述 2021年夏天&#xff0c;LSH开开心心的骑着电动车出去玩&#xff0c;结果一不留神&#xff0c;他骑着电动车进入了一只恶犬的领地。恶犬发现它的领地被LSH侵犯了&#xff0c;立马去追LSH&#xff0c;准备咬他一大口。LSH慌忙逃窜&#xff0c;但是他的电动车电量即将耗…

电力电子中的电大、电小尺寸?

01 前言 大家好&#xff0c;这期我们聊一下电力电子中的电大尺寸和电小尺寸。对于大部分电力电子应用工程师来说&#xff0c;可能并不太清楚电尺寸的概念。因为要谈到电尺寸就要考虑电信号的传播速度&#xff0c;一般会在高频、超高频电路中有所涉及&#xff0c;而大部分硅基…

【优秀python系统毕设】基于Python flask的气象数据可视化系统设计与实现,有LSTM算法预测气温

第一章 绪论 1.1 研究背景 在当今信息爆炸的时代&#xff0c;气象数据作为重要的环境信息资源&#xff0c;扮演着关键的角色。然而&#xff0c;传统的气象数据呈现方式存在信息量庞大、难以理解的问题&#xff0c;限制了用户对气象信息的深入理解和利用。因此&#xff0c;基…

[算法题]非对称之美

题目链接: 非对称之美 题目要求求最长非回文子字符串的长度, 那么如果字符串本身不是回文串, 那么长度就是该字符串本身的长度: 如果字符串本身是一个回文串, 那么只需把该字符串去掉一个字母后, 该字符串就不是回文串了, 长度也就是原本的长度减 1, 即: 所以想要求最长非回文…

BCH码误码率ber性能仿真(MATLAB)

BCH码 不同于奇偶校验码只能检验数据传输是否出错&#xff0c;BCH码可以实现对数据的检验和纠错 BCH&#xff08;n&#xff0c;k&#xff09;中的n代表总码元&#xff0c;k代表有效码元&#xff0c;相应的n-k即代表纠错码元 本文着重比较分析BCH(255,207),BCH(255,131),BCH(255…

iOS 自定义 仿苹果地图 半屏滑动效果控件

前言 在前一篇文章AI编程探索- iOS 实现类似苹果地图 App 中的半屏拉起效果我们通过三方库实现了这个功能。可是我发现这个三方不能加阴影效果。也许是我不知道怎么加吧&#xff01;于是只有自己搞咯&#xff01; 拆解功能 这功能给人在感觉上&#xff0c;有点麻烦&#xff0…

奇怪的Excel单元格字体颜色格式

使用VBA代码修改单元格全部字符字体颜色是个很简单的任务&#xff0c;例如设置A1单元格字体颜色为红色。 Range("A1").Font.Color RGB(255, 0, 0)有时需要修改部分字符的颜色&#xff0c;如下图所示&#xff0c;将红色字符字体颜色修改为蓝色。代码将会稍许复杂&am…

【MySQL进阶之路 | 高级篇】MVCC三剑客:隐藏字段,Undo Log,ReadView

1. 再谈隔离级别 我们知道事务有四个隔离级别&#xff0c;可能存在三种并发问题&#xff1a; 在MySQL中&#xff0c;默认的隔离级别是可重复读&#xff0c;可以解决脏读和不可重复读的问题&#xff0c;如果仅从定义的角度来看&#xff0c;它并不能解决幻读问题。如果我们想要解…

如何用find命令按文件大小快速查找并美化输出显示

背景 在系统中使用find命令查找大于20MB的文件非常简单&#xff0c;但默认情况下&#xff0c;输出结果中只显示文件路径&#xff0c;而不显示文件大小。如下图所示&#xff1a; 如果输出中能够同时显示文件大小&#xff0c;并且对内容进行适当的着色&#xff0c;这将显著提高其…

“论软件测试中缺陷管理及其应用”写作框架,软考高级论文,系统架构设计师论文

原创范文 软件缺陷指的是计算机软件或程序中存在的某种破坏正常运行能力的问题、错误&#xff0c;或者隐藏的功能缺陷。缺陷的存在会导致软件产品在某种程度上不能满足用户的需要。在目前的软件开发过程中&#xff0c;缺陷是不可避免的。软件测试是发现缺陷的主要手段&#xf…

【信创】udisk2服务异常导致U盘使用中自动移除问题解决

原文链接&#xff1a;【信创】udisk2服务异常导致U盘使用中自动移除问题解决 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于在信创终端操作系统上由于udisk2服务异常导致U盘等移动设备在使用中自动移除问题的排查文章。udisk2是一个管理存储设备的服务&#xf…

全球性“微软蓝屏”事件及其对网络安全和系统稳定性的深远影响

近日&#xff0c;一次由微软视窗系统软件更新引发的全球性“微软蓝屏”事件&#xff0c;不仅成为科技领域的热点新闻&#xff0c;更是一次对全球IT基础设施韧性与安全性的深刻检验。这次事件源于美国电脑安全技术公司“众击”提供的一个带有“缺陷”的软件更新&#xff0c;它如…

2024年起重信号司索工(建筑特殊工种)证模拟考试题库及起重信号司索工(建筑特殊工种)理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年起重信号司索工(建筑特殊工种)证模拟考试题库及起重信号司索工(建筑特殊工种)理论考试试题是由安全生产模拟考试一点通提供&#xff0c;起重信号司索工(建筑特殊工种)证模拟考试题库是根据起重信号司索工(建筑特…

学习硬件测试02:系统框图讲解+时钟树讲解+标准程序框架详解(P47~P49)

一、系统框图讲解 二、时钟树讲解 三、标准程序框架详解

记录|博图中VB脚本和子程序之间的区别?

目录 前言一、VB脚本1. 基本认知2. Function类型中的参数3. 对比看Function和Sub4. 运行VB脚本 更新时间 前言 VB脚本函数与子程序的区别 看到博途中有个VB脚本&#xff0c;感觉和编程相关&#xff0c;想知道下VB脚本能干什么&#xff1f;能否解决生成日志等问题。 一、VB脚本 …