【vector题解】只出现一次的数字 | 电话号码的数字组合
只出现一次的数字
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
给你一个整数数组 nums
,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。
你必须设计并实现线性时间复杂度的算法且仅使用常量额外空间来解决此问题。
示例 1:
输入:nums = [1,2,1,3,2,5]
输出:[3,5]
解释:[5, 3] 也是有效的答案。
示例 2:
输入:nums = [-1,0]
输出:[-1,0]
示例 3:
输入:nums = [0,1]
输出:[1,0]
思路
思路一:看到去重,先排序
上篇我们总结出了一个经验:看到去重,就先排个序。把大小相同的放在一起,这样,假如一个数的左邻右舍都跟它不一样,那这个数就是只出现了一次的那个。
这个道理 同样可应用于 这题。
class Solution {
public:vector<int> singleNumber(vector<int>& nums) {int sz = nums.size();vector<int> ret;//先考虑只有2 个元素的特殊情况if (sz == 2) { for (int e : nums) {ret.push_back(e);}return ret;}//先排序,让相同的挨在一起sort(nums.begin(), nums.end());//通过左邻右舍 来判断是否形单影只for (int i = 0; i < sz; i++) {if (i == 0 && nums[i] != nums[i + 1]) {ret.push_back(nums[i]);}else if (i == sz - 1 && nums[i] != nums[i - 1]) {ret.push_back(nums[i]);}else if (i>0 && i<sz-1&&nums[i] != nums[i - 1] && nums[i] != nums[i + 1]) {{ret.push_back(nums[i]);}}}return ret;}
};
我的错误记录:
我一开始,在if else的条件上出了bug
for (int i = 0; i < sz; i++) {if (i == 0 && nums[i] != nums[i + 1]) {ret.push_back(nums[i]);}else if (i == sz - 1 && nums[i] != nums[i - 1]) {ret.push_back(nums[i]);}else{if(nums[i] != nums[i - 1] && nums[i] != nums[i + 1]){ret.push_back(nums[i]);}}
}
出了bug不要怕,我们来看看它的报错内容:vector subscript out of range(subscript“下标”,数组下标超出范围)
经过检查发现:
当i=0时,它走不了前两条if。由于第三个else没设条件判断的门槛,所以i=0直接就进入了,进去以后,i-1导致下标越界。
所以说,if else语句的条件判断要多加小心!
思路二:位运算
(假设那俩不相等的数为a、b)
Step 1.先将所有数字异或在一起,得到一个非0的值ret。
为什么ret一定非0呢?因为只有当所有数字都是成对相同的出现时,ret才会为0,而这里明确了有两个不相等的数字。
因为相等的数异或 会抵消为0,所以这个ret就是a和b异或的值。
Step 2.假设得到的ret是101000,那为1的比特位 就是一道“分水岭”,因为这个比特位上,一定是0和1异或在一起,才会得到1。
所以,我们可以找到ret中最低位的那个1,这个比特位把数组元素分为两大阵营:组A. 此比特位为0 ,组B. 此比特位为1。
Step 3. 组A内的所有元素异或在一起,得到a;组B内的所有元素异或在一起,得到b。
class Solution {
public:vector<int> singleNumber(vector<int>& nums) {int ret=0;for(int e:nums){ret^=e;}//找到为1的最低比特位int i=0;for(i=0;i<32;i++){if((ret>>i)&1==1){break;}}//分组int group1_ret=0,group2_ret=0;for(int e:nums){if((e>>i)&1==1){ //该比特位为1的为group1group1_ret^=e;}else{ //该比特位为1的为group2group2_ret^=e;}}return {group1_ret,group2_ret}; }
};
电话号码的字母组合
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
给定一个仅包含数字 2-9
的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例 1:
输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
示例 2:
输入:digits = ""
输出:[]
示例 3:
输入:digits = "2"
输出:["a","b","c"]
思路
假设digits="23",我们把2、3视为“一层”:
遍历每一层,用n次递归的方式。
遍历一层中的每一个元素,用范围for。
class Solution {
public:string num_to_str[10]={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
void combine_letter(string digits,int di,string unit_ret,vector<string>& ret){if(di==digits.size()){ret.push_back(unit_ret); //每一层访问完毕,得出一个unit_ret return; }int n=digits[di]-'0';string str=num_to_str[n];for(auto c:str){combine_letter(digits,di+1,unit_ret+c,ret); //访问下一层}}vector<string> letterCombinations(string digits) {vector<string> ret;string unit_ret;if(digits==""){ //先考虑特殊情况return ret;}combine_letter(digits,0,unit_ret,ret);return ret; }
};
注意:1.要将数组num_to_str设为类域里的全局变量,这样函数combine_letter就能直接访问了。
我一开始把数组num_to_str写在函数letterCombinations里,并用static修饰,使之成为静态的局部变量。
然而,我弄混了,静态的局部变量并不会改变它的作用域,只是使它的生命周期变长了。
static局部变量出作用域不会被销毁,但是别的函数是没法访问到它的,它的作用域不变。
正确的做法是写在letterCombinations外,使之称为(类域里的)全局变量。
失败记录
虽然我知道,能用递归写的循环也能写,但这道题我还是不会循环的写法,花了好多时间……
用递归的好处是能把复杂的大事 转化成 好解决的小事。
第一次没写出来,我就去看题解。结果递归那一块老是不懂,好晕。这时,最好的办法是,打开IDE,把代码拷进去,自己调试时走一遍代码,就能理解透了:
现在我们来梳理下这个递归:
➡️一开始错误的认知:(假设digits==“23”):
我以为,先是找到2对应的a,给a开个栈帧,在此栈帧里找到3对应的d,给d开栈帧,然后再开新栈帧;最后,新栈帧、d的栈帧、a的栈帧逐一销毁。
再开b的栈帧……
➡️正确的认知:
而实际上,开新栈帧的因素是di。di==0时,开栈帧1号;在栈帧1号里,di ==1,开栈帧2号;在栈帧2号里,di ==2,开栈帧3号。
然后,3号销毁,而2号并不会随之销毁。2号栈帧里要完成对def三个字母的遍历,所以,会开3次栈帧3号。
当def三个字母都完成啦遍历,栈帧2号才会销毁,此时回到栈帧1号。
栈帧1号同样要完成abc三个字母的遍历,才会销毁。所以,一共开3次栈帧2号,每个栈帧2号里又要开3次栈帧3号,一共开9次栈帧3号。
要注意的细节
➡️1.注意区分+和+= !
+:用来计算两个数值的和,计算结束后会产生一个新的值。
+=:用来计算两个数值的和,计算结果会赋值给+=运算符前的参数。
拿这里来举例:
for(auto c:str){combine_letter(digits,di+1,unit_ret+c,ret);
}
写法一:unit_ret+c的结果 作为新的unit_ret参数,传给下一个调用的combine_letter函数,而实际上,unit_ret的值并未被改变。
如果写成这样,就错了:
for(auto c:str){unit_ret+=c; //写法二combine_letter(digits,di+1,unit_ret,ret);
}
写法二:unit_ret+c的结果会赋给unit_ret,拷贝unit_ret的值作为形参,传给下一个调用的combine_letter函数。unit_ret的值被改变。
➡️2.unit_ret注意是传值传参!不能传引用传参。
void combine_letter(string digits,int di,string unit_ret,vector<string>& ret);
为什么不能传引用传参呢?
如果传引用过去,那在这一步里,unit_ret每次加的c,都会保留下来。而如果传值传参,每个栈帧里的unit_ret都是拷贝出来的值,当栈帧销毁,拷贝的unit_ret也就销毁了,而实际的unit_ret不受影响。
for(auto c:str){combine_letter(digits,di+1,unit_ret+c,ret); //访问下一层
}
相关文章:

【vector题解】只出现一次的数字 | 电话号码的数字组合
只出现一次的数字 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 给你一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。 你必须设计并…...

VS2022 开发方式
使用 C# 在VS 2022 上开发时,发现有多种项目类型可以创建。这些类型放一起容易搞混,于是记录一下各种类型的区别。 这里主要介绍windows控制台程序、MFC程序、WPF程序、WinForm程序的特点。 创建哪种应用? 创建控制台应用 Windows控制台程序…...

【Python语言速回顾】——数据可视化基础
目录 引入 一、Matplotlib模块(常用) 1、绘图流程&常用图 编辑 2、绘制子图&添加标注 编辑 3、面向对象画图 4、Pylab模块应用 二、Seaborn模块(常用) 1、常用图 2、代码示例 编辑 编辑 编辑 …...

java实现pdf文件添加水印,下载到浏览器
java实现pdf文件添加水印,下载到浏览器 添加itextpdf依赖 <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.8</version> </dependency>文件下载到浏览器和指定路径 …...

代码随想录算法训练营第四十一天丨 动态规划part04
01背包理论基础 见连接:代码随想录 416. 分割等和子集 思路 01背包问题 背包问题,大家都知道,有N件物品和一个最多能背重量为W 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解…...

PyCharm免费安装和新手使用教程
简介 PyCharm是一款由JetBrains公司开发的Python集成开发环境(IDE)。它提供了一系列强大的功能,包括自动代码完成、语法高亮、自动缩进、代码重构、调试器、测试工具、版本控制工具等,使开发者可以更加高效地开发Python应用程序。…...
使用Python的Scikit-Learn进行决策树建模和可视化:以隐形眼镜数据集为例
决策树是一种强大的机器学习算法,它在数据挖掘和模式识别中被广泛应用。决策树模型可以帮助我们理解数据中的模式和规则,并做出预测。在本文中,我们将介绍如何使用Python的Scikit-Learn库构建决策树模型,并使用Graphviz进行可视化…...
开源软件:释放创新的力量,改变数字世界的游戏规则
在充满活力的技术领域,创新是至高无上的,有一种方法已获得显著的吸引力——开源软件。开源软件凭借其透明、协作和无限可能性的精神,彻底改变了我们开发、共享和定制应用程序的方式。从操作系统到数据分析工具,其影响跨越了多个领…...

【QT】鼠标常用事件
新建项目 加标签控件 当鼠标进去,显示【鼠标进入】,离开时显示【鼠标离开】 将QLable提升成自己的控件,然后再去捕获 添加文件 改继承的类名 提升类 同一个父类,可以提升 效果 现在代码就和Qlabel对应起来了。 在.h中声明&…...
LuatOS-SOC接口文档(air780E)--mlx90640 - 红外测温(MLX90640)
常量# 常量 类型 解释 mlx90640.FPS1HZ number FPS1HZ mlx90640.FPS2HZ number FPS2HZ mlx90640.FPS4HZ number FPS4HZ mlx90640.FPS8HZ number FPS8HZ mlx90640.FPS16HZ number FPS16HZ mlx90640.FPS32HZ number FPS32HZ mlx90640.FPS64HZ number FPS6…...
java连接本地数据库可以简写为///
java连接数据库配置文件写为: server:port: 8091 spring:application:name: user-managerdatasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/user?serverTimezoneAsia/Shanghai&characterEncodingutf-8username: root…...

基于springboot漫画动漫网站
基于springbootvue漫画动漫网站 摘要 基于Spring Boot的漫画动漫网站是一个精彩的项目,它结合了现代Web开发技术和漫画爱好者的热情。这个网站的目标是为用户提供一个便捷的平台,让他们能够欣赏各种漫画和动漫作品,与其他爱好者分享他们的兴趣…...
autoFac 生命周期 试验
1.概述 autoFac的生命周期 序号名称说明1InstancePerDependency每次请求都创建一个新的对象2InstancePerLifetimeScope同一个Lifetime生成的对象是同一个实例3SingleInstance每次都用同一个对象 2.注 InstancePerLifetimeScope 同一个Lifetime生成的对象是同一个实例&#x…...
foreach、for in 和for of的区别?
forEach,for...in 和 for...of 是 JavaScript 中用于遍历数据的三种不同的结构。它们在遍历数组、对象和可迭代对象(如 Set 和 Map)时非常有用。尽管它们都可以用于循环遍历,但它们之间存在一些重要的区别: forEach&a…...

【Effective C++】条款45: 运用成员函数模板接受所有兼容的类型
假设有如下继承结构: class Top{}; class Middle: public Top{}; class Bottom: public Middle{};public继承意味着is-a关系,所有的基类都是派生类,但反之则不是,例如所有的学生都是人,但不是所有的人都是学生. 派生类到基类的指针可以直接隐式转换 Top* pt1 new Middle; T…...
WSL1 安装 debian xfce 用xrdp 导入远程桌面
凑合能用 晃晃行 晃晃不行 而且比较卡 还经常报崩溃 sudo apt install xfce4 xfce4-goodies xorg dbus-x11 x11-xserver-utils apt install locales -y 安装过完应该会提示设置locales,如果安装完之后想要更改相关设置,可以使用如下命令重新设置loca…...

WPF RelativeSource属性-目标对象类型易错
上一篇转载了RelativeSource的三种用法,其中第二种用法较常见,这里记录一下项目中曾经发生错误的地方,以防自己哪天忘记了,又犯了同样错误—WPF RelativeSource属性-CSDN博客 先回顾一下: 控件关联其父级容器的属性—…...

Java while 和do while 循环
循环是程序中的重要流程结构之一。循环语句能够使程序代码重复执行,适用于需要重复一段代码直到满足特定条件为止的情况。 所有流行的编程语言中都有循环语句。Java 中采用的循环语句与C语言中的循环语句相似,主要有 while、do-while 和 for。 另外 Ja…...
应用软件安全编程--03净化传递给 Runtime.exec() 方法的非受信数据
每个 Java 应用都有一个 Runtime 类的实例, 一般需要使用 shell 时调用它,从而可以在 POSIX 中 使用/bin/sh 或者在Windows 平台中使用cmd.exe。 当参数中包含以空格、双引号或者其他以一/开头 的用来表示分支的字符时,就可能发生参数注入攻…...
uniapp阻止冒泡的方法,点击事件嵌套点击事件,怎么阻止同时触发
uniapp阻止冒泡的方法 当我们遇到点击事件嵌套点击事件的时候,点击里边的事件,外边的也会跟着触发该怎么办? 起初我尝试用了css里的修改z-index属性的方法,把里边的<view>标签放在上边,结果两个事件还是同时触发…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向
在人工智能技术呈指数级发展的当下,大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性,吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型,成为释放其巨大潜力的关键所在&…...
规则与人性的天平——由高考迟到事件引发的思考
当那位身着校服的考生在考场关闭1分钟后狂奔而至,他涨红的脸上写满绝望。铁门内秒针划过的弧度,成为改变人生的残酷抛物线。家长声嘶力竭的哀求与考务人员机械的"这是规定",构成当代中国教育最尖锐的隐喻。 一、刚性规则的必要性 …...
Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解
文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 问题可视化2.2 核心挑战 3. 解法一:HashSet 标记访问法3.1 算法思路3.2 Java代码实现3.3 详细执行过程演示3.4 执行结果示例3.5 复杂度分析3.6 优缺点分析 4. 解法二:Floyd 快慢指针法(…...

针对药品仓库的效期管理问题,如何利用WMS系统“破局”
案例: 某医药分销企业,主要经营各类药品的批发与零售。由于药品的特殊性,效期管理至关重要,但该企业一直面临效期问题的困扰。在未使用WMS系统之前,其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...

结构化文件管理实战:实现目录自动创建与归类
手动操作容易因疲劳或疏忽导致命名错误、路径混乱等问题,进而引发后续程序异常。使用工具进行标准化操作,能有效降低出错概率。 需要快速整理大量文件的技术用户而言,这款工具提供了一种轻便高效的解决方案。程序体积仅有 156KB,…...
uniapp获取当前位置和经纬度信息
1.1. 获取当前位置和经纬度信息(需要配置高的SDK) 调用uni-app官方API中的uni.chooseLocation(),即打开地图选择位置。 <button click"getAddress">获取定位</button> const getAddress () > {uni.chooseLocatio…...