当前位置: 首页 > news >正文

只出现一次的数字(暴力、哈希查重、异或运算)

目录

一.题目

题目解析

题目链接

二.解题过程

俗手(暴力:数组模拟哈希表)

思路

代码示例

提交情况

本手:哈希查重

思路

代码示例

提交情况

妙手:异或运算

思路

代码示例

提交情况


作者的个人gitee

作者的算法讲解主页▶️

每日一言:“行到水穷处,坐看云起时🌸🌸


一.题目

只出现一次的数字

给定一个非空整数数组 nums,除了某个元素只出现一次以外,其余每个元素均出现两次。请找出那个只出现一次的元素。

你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。

示例输入输出
示例 1nums = [2,2,1]1
示例 2nums = [4,1,2,1,2]4
示例 3nums = [1]1

提示

  • 1 <= nums.length <= 3 * 10^4

  • -3 * 10^4 <= nums[i] <= 3 * 10^4

  • 除了某个元素只出现一次以外,其余每个元素均出现两次

题目解析

查重问题除了暴力解法最先想到的肯定是哈希,但这道题似乎另有妙手...?

题目链接

136. 只出现一次的数字 - 力扣(LeetCode)

二.解题过程

俗手(暴力:数组模拟哈希表)

  • 思路

题目要求找到只出现一次的元素,关于查重的问题,我们很轻易地就能想到创建一个哈希表来记录每个元素出现的次数。但此题不用真正创建一个unordered_map,我们可以用数组来模拟哈希表。需要注意的是:虽然哈希查找的时间复杂度较低,但此题数组的空间开销较大,也会导致运行时间增加。

时间复杂度:O(n)。

  • 代码示例

class Solution {
public:int singleNumber(vector<int>& nums) {//创建一个哈希表//元素值充当索引,其数据范围是-3*(10^4)~3*(10^4),可能是负数//所以我们要创建一个(2*nums.size()+1)大小的数组来存储元素的出现次数vector<int> hash(60002);//遍历数组for (int i = 0; i < nums.size(); i++) {    //将数组内元素出现的次数存储在hash表中//数组下标不能为负数,所以我们要+30001,将数组索引全部转化为正数区间hash[nums[i] + 30001]++; }//遍历哈希表,找到出现次数为1的元素,并返回for (int i = 0; i < nums.size(); i++) {if (hash[nums[i] + 30001] == 1) {return nums[i]; }}return 0; }
};

  • 提交情况

img编辑

本手:哈希查重

  • 思路

创建一个unodered_map记录数组元素出现的个数,遍历哈希表找到次数为1的元素。返回索引。

时间复杂度:O(n)

  • 代码示例

​
class Solution 
{
public:int singleNumber(vector<int>& nums) {//创建哈希表unordered_map<int, int> hash;
​//创建变量存储结果int res = 0;
​//遍历数组for (int key : nums) {//如果key不存在于hash中,则将他的次数初始化为1if (hash.find(key) == hash.end()) {hash[key] = 1;} 
​//存在的话则次数++else {hash[key]++;}}
​//遍历哈希表for (auto& pair : hash) {//如果出现的次数是1则将索引赋给res,之后breakif (pair.second == 1) {res = pair.first;break;}}//返回结果return res;}
};​
  • 提交情况

img

妙手:异或运算

  • 思路

方法一、二的时间复杂度较高,因此我们用一种更快的算法来解决。

由题目信息可知,n个元素中有(n-1)个元素都出现了两次,只有1个数据出现了一次,要求我们找到出现1次的数字。这就不妨联想到异或运算的性质。

由异或运算的运算性质可知:一个数与自己异或的值是0,而0与任何非0数字异或都是非0数字本身,且异或运算满足交换律与结合律。

那么我们就可以遍历数组,使数组内元素相互异或,在交换律与结合律的基础上可以推出最后出现的数字一定就是只出现一次的数字。

时间复杂度:O(1)。

  • 代码示例

class Solution 
{
public:int singleNumber(vector<int>& nums) {int ret = 0;//遍历数组,使数组内所有元素相互异或,得到只出现一次的数字。for(auto x:nums){ret = ret^x;}return ret;}
};
  • 提交情况

img


觉得有帮助的话麻烦点个赞和关注吧,秋梨膏QAQ!

相关文章:

  • 交流中的收获-250508
  • 云手机虚拟地址技术的运营场景
  • FreeRTOS如何检测内存泄漏
  • ConcurrentHashMap解析
  • Java高频面试之并发编程-14
  • 设备管理系统深度测评:如何用 AI 知识库实现故障智能诊断?
  • 沃伦森电容器支路阻抗特性监控系统 电容器组智能健康管理专家
  • 模拟内存管理
  • 工程管理系统简介 工程管理系统源码 java工程管理系统 工程管理系统功能设计 从架构到实操
  • 若依框架Ruoyi-vue整合图表Echarts中国地图标注动态数据
  • TCP/IP和OSI对比
  • 果汁厂通信革新利器:Ethernet/IP转CANopen协议网关
  • 网盘解析工具更新,支持UC网盘!!
  • 从艾米・阿尔文看 CTO 的多面特质与成长路径
  • 使用DEEPSEEK快速修改QT创建的GUI
  • LLM 论文精读(三)Demystifying Long Chain-of-Thought Reasoning in LLMs
  • 深度学习笔记41_调用Gensim库训练Word2Vec模型
  • 什么是:Word2Vec + 余弦相似度
  • 又双叒叕想盘一下systemd
  • Lua从字符串动态构建函数
  • 新村回响:一周城市生活
  • 首批证券公司科创债来了!拟发行规模超160亿元
  • 视频丨习近平同普京会谈:共同弘扬正确二战史观,维护联合国权威和地位
  • 汪明荃,今生不负你
  • 央行:增加支农支小再贷款额度3000亿元
  • 2025五一档电影票房破7亿