算法刷题Day24 | 216.组合总和III、17.电话号码的字母组合

目录

  • 0 引言
  • 1 组合总和 III
    • 1.1 我的解题
  • 2 电话号码的字母组合
    • 2.1 我的解题
    • 2.2 优秀的题解

请添加图片描述

  • 🙋‍♂️ 作者:海码007
  • 📜 专栏:算法专栏
  • 💥 标题:算法刷题Day24 | 216.组合总和III、17.电话号码的字母组合
  • ❣️ 寄语:书到用时方恨少,事非经过不知难!

0 引言

下午脑子还算清醒,直接刷题。

1 组合总和 III

  • 🎈 文档讲解
  • 🎈 视频讲解
  • 🎈 做题状态:

1.1 我的解题

其实可以把问题拆分成两个问题。首先找出数字1到9中 k 个数的所有组合的情况有多少。然后再判断和为n的情况有哪些。就可以解决本问题了。

回溯三部曲:

  1. 确定参数和返回值:一个 int 参数记录从哪里开始遍历,参数 k,参数 n,参数path,参数paths
  2. 确定递归终止条件:当path的大小为k时终止,然后判断当前path中数据之和是否为 n,如果为n则添加到paths中。
  3. 确定单层回溯逻辑:选择节点,递归,撤销选择。

在第一次写的时候,有点地方没有太注意,就是递归的时候
backTracing(path, paths, i + 1, k, n); 这行代码一定是传入 i+1 ,而不是 firstIndex + 1。因为在这个叉树遍历的时候同一层的 firstIndex 变量的值是同样的,但是对于同一层来说其实他们遍历开始的地方是不一样的。因该传入的是 i+1 才是正确。

class Solution
{
public:
	void backTracing(vector<int>& path, vector<vector<int>>& paths, int firstIndex, int k, int n)
	{
		if (path.size() == k)
		{
			int sum = 0;
			for (auto data : path)
			{
				sum += data;
			}
			if (sum == n)
			{
				paths.push_back(path);
			}
			return;
		}

		// 剪枝
		int maxCount = 9 - firstIndex + 1 + path.size();
		if (maxCount < k)
		{
			return;
		}

		// 回溯
		for (int i = firstIndex; i < 10; i++)
		{
			path.push_back(i);
			backTracing(path, paths, i + 1, k, n);
			path.pop_back();
		}
	}

	vector<vector<int>> combinationSum3(int k, int n) 
	{
		vector<vector<int>> res;
		vector<int> path;
		backTracing(path, res, 1, k, n);
		return res;
	}
};

2 电话号码的字母组合

  • 🎈 文档讲解
  • 🎈 视频讲解
  • 🎈 做题状态:

2.1 我的解题

说这道题有点难,那么我先看二十分钟题目吧。

我的解题思路有点复杂,但是好歹是做出来了。主要思路就是根据字母来确定 firstIndex 要增加多少而已。

class Solution
{
public:
	map<char, int> num2char = { 
		{'a', 3},
		{'b', 2}, 
		{'c', 1},
		{'d', 3},
		{'e', 2},
		{'f', 1},
		{'g', 3},
		{'h', 2},
		{'i', 1},
		{'j', 3},
		{'k', 2},
		{'l', 1},
		{'m', 3},
		{'n', 2},
		{'o', 1},
		{'p', 4},
		{'q', 3},
		{'r', 2},
		{'s', 1},
		{'t', 3},
		{'u', 2},
		{'v', 1},
		{'w', 4},
		{'x', 3},
		{'y', 2},
		{'z', 1},
	};

	void backTracing(string& path, vector<string>& paths, int firstIndex, string& character, int size)
	{
		// 终止条件
		if (path.size() == size)
		{
			paths.push_back(path);
			return;
		}

		// 单层回溯逻辑
		for (int i = firstIndex; i < character.size(); i++)
		{
			path.push_back(character[i]);
			backTracing(path, paths, i + num2char[character[i]], character, size);
			path.pop_back();
		}
	}

	vector<string> letterCombinations(string digits) 
	{
        if (digits.size() == 0) return {};
		// 1. 先将数字转换成字母
		string character;
		for (auto str : digits)
		{
			if (str == '2')
			{
				character += "abc";
			}
			else if (str == '3')
			{
				character += "def";
			}
			else if (str == '4')
			{
				character += "ghi";
			}
			else if (str == '5')
			{
				character += "jkl";
			}
			else if (str == '6')
			{
				character += "mno";
			}
			else if (str == '7')
			{
				character += "pqrs";
			}
			else if (str == '8')
			{
				character += "tuv";
			}
			else
			{
				character += "wxyz";
			}
		}

		// 2. 回溯算法
		string path;
		vector<string> paths;
		backTracing(path, paths, 0, character, digits.size());
		return paths;
	}

};

2.2 优秀的题解

使用一个vector <string> letterMap 数组来根据数字确定字母集合。如下面所示, letterMap[number] 就可以取到数字对应的字母集合了。

	const vector<string> letterMap = {
		"",		// 0
		"",		// 1
		"abc",	// 2
		"def",	// 3
		"ghi",	// 4
		"jkl",	// 5
		"mno",	// 6
		"pqrs",	// 7
		"tuv",	// 8
		"wxyz",	// 9
	};

在这里插入图片描述

改进后的代码如下。

思考:之前写的组合都需要传入一个 firstIndex 的变量作为遍历开始的标识,为什么这道题目不需要了。之前需要时因为不同层遍历的数据都是同一份,而且,不同层遍历的开始位置不同,所以需要传入一个参数标记起始位置。
但是本道题,不同层遍历的数据是不同的,所以就不需要传入标识了。

同一层的遍历起始不也不同吗?为什么不需要,那是因为同一层是属于一个递归函数,在for循环中已经有i++改变遍历的起始位置了。

#include <iostream>
#include <vector>
#include <string>

using namespace std;

class Solution
{
public:
	const vector<string> letterMap = {
		"",		// 0
		"",		// 1
		"abc",	// 2
		"def",	// 3
		"ghi",	// 4
		"jkl",	// 5
		"mno",	// 6
		"pqrs",	// 7
		"tuv",	// 8
		"wxyz",	// 9
	};

	void backTracing(string& path, vector<string>& paths, string digits)
	{
		// 终止条件
		if (path.size() == digits.size())
		{
			paths.push_back(path);
			return;
		}

		// 单层递归逻辑
		// 当前层应该循环的遍历的字母集
		string character = letterMap[digits[path.size()] - '0'];
		for (int i = 0; i < character.size(); i++)
		{
			path.push_back(character[i]);
			backTracing(path, paths, digits);
			path.pop_back();
		}
	}

	vector<string> letterCombinations(string digits) 
	{
		string path;
		vector<string> paths;
		backTracing(path, paths, digits);
		return paths;
	}

};

int main()
{
	string digits;
	cin >> digits;

	Solution mySolution;
	vector<string> res = mySolution.letterCombinations(digits);

	return 0;
}

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

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

相关文章

Linux基础篇:Linux第三方软件仓库——可以让Linux变得有趣的软件仓库

Linux第三方软件仓库——可以让Linux变得有趣的软件仓库 一、epel源介绍 EPEL&#xff08;Extra Packages for Enterprise Linux&#xff09;源是一个由Fedora项目组维护的第三方软件仓库&#xff0c;为企业级Linux发行版&#xff08;如Red Hat Enterprise Linux&#xff08;…

opencv+python(通道的分离与合并)笔记

分割图像通道&#xff1a; 通过函数mvsplit(img)&#xff1b;mv返回的通道&#xff1b; RGB有3个通道&#xff1b;灰度图只有一个通道&#xff1b; b,g,r cv2.split(img)cv2.imshow("b",b)#通道bcv2.imshow("g",g)#通道gcv2.imshow("r",r)#通道…

Flutter 应用数据持久化指南

1. 介绍 1.1 什么是数据持久化&#xff1f; 数据持久化是指将应用程序中的数据保存在持久存储介质&#xff08;如硬盘、数据库等&#xff09;中的过程。在计算机科学领域&#xff0c;持久化数据是指数据在程序退出或系统关机后仍然存在的能力。这种持久性使得数据可以在不同的…

为什么说“微隔离技术“ 那么重要,德迅零域给您答案

随着网络安全威胁不断增加&#xff0c;传统安全措施难以承受这种压力&#xff0c;人们需要更强大的防护工具来确保个人和组织的数据不会被攻击者窃取。 “微隔离”技术是一种在设备内部进行隔离的安全机制。它基于各种硬件或软件实现不同隔离策略&#xff0c;将不同的数据或应用…

C++——STL容器——string

目录 1.构造函数 模拟实现 2.析构函数 模拟实现 3.string遍历 3.1 c_str、size、lenth、capacity等 模拟实现 3.2 字符串元素访问 3.2.1 []操作符重载、at 模拟实现 3.2.2 front、back等 3.3 迭代器 模拟实现 4.赋值操作 4.1 赋值重载函数 模拟实现 4.2 assig…

C#手术麻醉信息系统源码,技术框架:Vue,Ant-Design+百小僧开源框架

C#手术麻醉信息系统源码&#xff0c;技术框架&#xff1a;Vue&#xff0c;Ant-Design百小僧开源框架 手术麻醉系统主要用于在手术过程中监测和控制患者的状态&#xff0c;确保手术的顺利进行并保障患者的生命安全。该系统通过一系列先进的医疗设备和技术&#xff0c;为手术患者…

【tensorflow框架神经网络实现鸢尾花分类—优化器】

文章目录 1、前言2、神经网络参数优化器2.1、SGD2.2、SGDM2.3、Adagrad2.4、RMSProp2.5、Adam 3、实验对比不同优化器4、结果对比 1、前言 此前&#xff0c;在【tensorflow框架神经网络实现鸢尾花分类】一文中使用梯度下降算法SGD&#xff0c;对权重 w w w和偏置 b b b进行更新…

多态.Java

&#xff08;1&#xff09;什么是多态&#xff1f; 同类型的对象&#xff0c;表现出不同的形态。前者指父类&#xff0c;后者指不同的子类 说简单点&#xff0c;就是父类的同一种方法&#xff0c;可以在不同子类中表现出不同的状态&#xff0c;或者说在不同子类中可以实现不同…

[技术闲聊]我对电路设计的理解(七)-Cadence原理图绘制

一、原理图软件推荐 之前的章节有讲过AD、PADS、Cadence&#xff0c;以及三者的应用标准&#xff0c;今天再讲讲这一点。 如果是学生&#xff0c;可以学习AD软件&#xff0c;因为学校在学习&#xff0c;上手容易&#xff0c;而且即使工作后&#xff0c;如果是电机控制等4层板或…

websokcet服务端实现

一/websokcet服务端实现 步骤一&#xff1a; springboot底层帮我们自动配置了websokcet&#xff0c;引入maven依赖 1 2 3 4 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</arti…

力扣刷题 二叉树遍历的统一迭代法

题干 给定一个二叉树的根节点 root &#xff0c;返回 它的 前中后序 遍历 。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,3,2]示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[]示例 3&#xff1a; 输入&#xff1a;root […

Python 之 Fastapi 框架学习

依赖安装 Fastapi 有版本要求&#xff0c;需要的 Python 版本至少是 Python 3.8&#xff08;不要犟&#xff0c;按照版本要求来&#xff0c;我最先也是在我 Python3.6 上装的&#xff0c;果不其然跑不起来&#xff09;&#xff0c;幸好我 Win7 老古董能支持的 Python 最高版本…

FastWiki发布`0.2.4`支持js 函数

Release v0.2.4 AIDotNet/fast-wiki (github.com) 支持JS动态functioncall调用支持动态function管理支持JS在线编辑提供智能代码提示支持JS在线编辑提供部分绑定的c#类&#xff08;默认提供Console&#xff0c;HttpClient&#xff09;支持Application绑定多个Function Call优…

跨站请求伪造漏洞(CSRF)

什么是CSRF CSRF&#xff08;Cross-Site Request Forgery&#xff09;&#xff0c;也被称为 one-click attack 或者 session riding&#xff0c;即跨站请求伪造攻击。 漏洞原理 跨站请求伪造漏洞的原理主要是利用了网站对用户请求的验证不严谨。攻击者会在恶意网站中构造一个…

linux 文件提权|属性修改

文章目录 suid&#xff08;set uid&#xff09;添加文件属性查看文件属性i &#xff08;immutable&#xff09; umask suid&#xff08;set uid&#xff09; 让文件在执行的时候具有属主&#xff08;对应文件 user &#xff09;的权限 chmod 7744 temp.txt 第一位的7表示权限位…

探寻大数据思想的主要贡献者与核心内容

引言&#xff1a; 在当今数字化时代&#xff0c;大数据已成为企业和科学研究的关键要素。其背后的思想和概念不仅引领了数据处理和分析的革新&#xff0c;也推动了人类对于信息时代的理解与认知。 大数据思想的起源&#xff1a; 在信息爆炸的时代背景下&#xff0c;大数据思…

海外仓的出入库流程有什么痛点?位像素海外仓系统怎么提高出入库效率?

随着跨境电商的蓬勃发展&#xff0c;海外仓是其中不可或缺的一个关键环节。而货物的出库与入库则是海外仓管理中的一个核心业务流程&#xff0c;它的运作效率直接影响到整个跨境物流的效率和客户体验。今天&#xff0c;让我们具体来看一看关于海外仓出入库的流程&#xff0c;其…

150行Python代码模拟太阳系行星运转

今天我们用Python来模拟一下太阳系行星运动轨迹~ 先上成品图&#xff08;运行效果含音乐的呦&#xff09; 想要实现这样的效果并不难 准备材料 首先我们需要准备这样一些材料 宇宙背景图 背景透明的行星图 编写代码 代码分块详解 导入需要的模块 import pygame import …

深度学习理论基础(六)多头注意力机制的自定义及Pytoch库的使用详细代码

目录 1. Scaled Dot-Product Attention2. 多头注意力机制框图&#xff08;1&#xff09;计算公式&#xff08;2&#xff09;具体计算过程&#xff08;3&#xff09;具体代码 深度学习中的注意力机制&#xff08;Attention Mechanism&#xff09;是一种模仿人类视觉和认知系统的…

轻量应用服务器4核8G12M配置优惠价格646元一年零3个月,12M公网带宽

腾讯云轻量4核8G12M服务器优惠价格646元15个月&#xff0c;买一年送3个月&#xff0c;配置为轻量4核8G12M、180GB SSD盘、2000GB月流量、12M带宽&#xff0c;腾讯云优惠活动页面 yunfuwuqiba.com/go/txy 活动链接打开如下图&#xff1a; 腾讯云4核8G服务器租用价格 腾讯云&…