只出现一次的数字(总结)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、给定一个整数数组nums,除了某个元素只出现一次以外,其余元素均出现两次。找出那个只出现一次的元素
  • 二、给你一个整数数组nums,除某个元素仅出现一次外,其余每个元素都恰出现三次。请你找出并返回那个只出现了一次的元素
  • 三、一个整型数组nums里除了两个数字之外,其他数字都出现了两次,请找出这两个只出现一次的数字。要求时间复杂度为O(n),空间复杂度是O(1)
  • 四、给定一个整数数组nums和一个整数k,除了某个元素仅出现一次外,其余每个元素都恰好出现了k次,请你找出并返回那个只出现了一次的元素


前言

我们在刷题的时候会碰到各种各样的《只出现一次的数字》的题目,在这里,我们对碰到的题目进行总结

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

异或的性质:

  • 0^x = x
  • x^x = 0; 同样的数异或两次得到零
  • 异或满足交换律和结合律,不需要考虑顺序

由于异或有以上的性质,所以我们可以将数组nums当中的元素依次进行异或操作,此时数组中出现两次的数进行异或后变成了0,而最终异或得到的结果就是只出现一次的那个数

int* singleNumber(int* nums, int numsSize, int* returnSize)
{//找出这个值放到数组int* arr = (int*)malloc(sizeof(int)* 1);//输出型参数,让外面拿到数组的长度*returnSize =1 ;int ret = 0;for (int i = 0; i < numsSize; ++i){ret ^= nums[i];}arr[0] = ret;return arr;
}

二、给你一个整数数组nums,除某个元素仅出现一次外,其余每个元素都恰出现三次。请你找出并返回那个只出现了一次的元素

int类型变量的大小是4个字节,也就是32个比特位。由于相同的数的二进制序列都是一样的,因此当我们遍历nums数组当中的数字,依次同级每个比特位出现1的次数时,就会出现以下几种情况:

  • 某一比特位出现1的次数为0,表明数组nums当中的所有数字的该比特位都为0,因此只出现一次的数字的该比特位也为0
  • 某一比特位出现1的次数对3取余后得到0值,表明数组nums中只出现一次的数字的该比特位为0
  • 某一比特位出现1的次数为3取余后得到非0值,表明数字nums中只出现一次的数字的该比特位为1

因此当我们遍历nums数组统计得到每个比特位出现1的次数之后,就可以将这32个值依次对3进行求余操作,最终得到的32个0/1序列就是只出现一次的数字的二进制序列

#include <stdio.h>
#include <stdlib.h>
int singleNumber(int* nums, int numsSize) 
{int ret = 0; // 初始化结果为0// 遍历整数的32个比特位for (int i = 0; i < 32; i++){int total = 0; // 用于统计当前比特位为1的元素个数// 遍历数组中的所有元素for (int j = 0; j < numsSize; j++) {// 将当前元素右移i位,然后与1进行与操作// 这样可以提取出第i个比特位的值(0或1)total += ((nums[j] >> i) & 1);}// 如果第i个比特位为1的元素个数不能被3整除// 则说明只出现一次的数字的这一比特位为1if (total % 3 != 0){// 使用位或操作将ret的第i个比特位设置为1ret |= (1 << i);}}return ret; // 返回只出现一次的数字
}// 示例使用
int main() {int nums[] = {2, 2, 3, 2}; // 示例数组,3是只出现一次的数字int size = sizeof(nums) / sizeof(nums[0]);int result = singleNumber(nums, size);printf("只出现一次的数字是: %d\n", result); // 应该输出3return 0;
}

我们也可以使用排序后遍历的方法,不过与位操作方法相比,位操作的时间复杂度为O(n),空间复杂度为O(1);排序后遍历的方法其复杂度为O(nlongn),空间复杂度为O(1)或O(n),但是其实现简单

使用数组排序后遍历

#include <stdio.h>
#include <stdlib.h>// 比较函数,用于qsort
int compare(const void* a, const void* b) {return (*(int*)a - *(int*)b);
}int singleNumber(int* nums, int numsSize) {// 先对数组进行排序qsort(nums, numsSize, sizeof(int), compare);// 遍历排序后的数组for (int i = 0; i < numsSize; i += 3) {// 如果当前元素与下一个元素不同,或者已经到达数组末尾if (i == numsSize - 1 || nums[i] != nums[i + 1]) {return nums[i];}}return -1; // 如果没有找到,返回-1
}

三、一个整型数组nums里除了两个数字之外,其他数字都出现了两次,请找出这两个只出现一次的数字。要求时间复杂度为O(n),空间复杂度是O(1)

数组nums当中除了出现一次的数字之外,剩下的都是出现两次的数字,但是我们不能直接遍历数组元素进行异或操作,因为此时nums数组当中有两个出现一次的数字,如果我们直接将所有数字进行异或,最终得到的实际就是这两个出现一次的数字相异或后的结果

如果我们可以将数组nums当中的数字分为两组,并且这两个出现一次的数字正好分别分到了两组,此时就相当于分别在这两个小组中找出现一次的数字,问题就回到了第一题

现在的问题就变成了,如何将这两个只出现一次的数字分到两个不同的组别中。
这个实际上很简单,因为我们直接对数组nums当中的元素进行异或操作,得到的实际上就是这两个只出现一次的数字相异或的结果,我们将结果称为ret。由于这两个只出现一次的数字的二进制序列是不同的,因此在ret的二进制序列当中一定至少存在一个不为0的比特位,而这两个只出现一次的数字的该比特位的值是不同的,一个为0,一个为1
因此我们可以根据该比特位来进行分组,将数组nums当中该比特位为1的数字分为一组,将该比特位为0的数字分到另一组,则这两个只出现一次的数字就一定被分到了两个不同的组当中,其他出现两次的数字,要么在这一组,要么在另一组

解题步骤如下:

  1. 遍历数组nums,对数组中的所有元素进行异或,得到异或后的结果ret
  2. 找出ret当中任意一个不为0的比特位记为j
  3. 将原数组分为两组,第j位为1的为a组,第j位为0的为b组
  4. x和y一定会分别进入a、b组,其他出现两次的数,要么进入a组,要么进入b组
  5. a组和b组数据就变成其他数出现2次,只有一个数出现1次
  6. 再对a、b组进行异或就可以找出x和y

在这里插入图片描述

int* singleNumber(int* nums, int numsSize, int* returnSize)
{   //1.计算所有元素的异或结果int ret = 0;for (int i = 0; i < numsSize; i++){ret ^= nums[i];}//2.找到ret中为1的任意一位(即x和y不同的位)int j = 0;while (((ret >> j) & 1) == 0){j++;}//3.根据第j位将数组分为两组,并分别计算异或int x = 0, y = 0;for (int k = 0; k < numsSize; k++){if ((nums[k] >> j) & 1){x ^= nums[k];}else{y ^= nums[k];}}//4.准备返回值int* arr = (int*)malloc(sizeof(int)* 2);arr[0] = x;arr[1] = y;*returnSize = 2;return arr;
}

四、给定一个整数数组nums和一个整数k,除了某个元素仅出现一次外,其余每个元素都恰好出现了k次,请你找出并返回那个只出现了一次的元素

数组中除了那个只出现一次的数字之外,无论其他数字出现多少次,我们实际都可以通过统计每个比特位出现1的次数的方式进行求解
只不过现在我们是将得到的32个比特位各自出现1的次数对k进行求余操作,最终得到的32个0/1序列也就是出现一次的数字的二进制序列

#include <stdio.h>
#include <stdlib.h>
int singleNumber(int* nums, int numsSize,int k)
{int ret = 0; // 初始化结果为0// 遍历整数的32个比特位for (int i = 0; i < 32; i++){int total = 0; // 用于统计当前比特位为1的元素个数// 遍历数组中的所有元素for (int j = 0; j < numsSize; j++){// 将当前元素右移i位,然后与1进行与操作// 这样可以提取出第i个比特位的值(0或1)total += ((nums[j] >> i) & 1);}// 如果第i个比特位为1的元素个数不能被k整除// 则说明只出现一次的数字的这一比特位为1if (total % k != 0){// 使用位或操作将ret的第i个比特位设置为1ret |= (1 << i);}}return ret; // 返回只出现一次的数字
}// 示例使用
int main() {int nums[] = { 2, 2, 3, 2 }; // 示例数组,3是只出现一次的数字int size = sizeof(nums) / sizeof(nums[0]);int k = 3;int result = singleNumber(nums, size,k);printf("只出现一次的数字是: %d\n", result); // 应该输出3return 0;
}

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

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

相关文章

Cesium 入门教程(十一):Camera相机功能展示

文章目录一&#xff0c;Cesium 实际示例&#xff08;含源代码&#xff09;1&#xff0c;vuecesium&#xff1a; 围绕一个固定点自动左右旋转2&#xff0c;vuecesium&#xff1a; flyto一个具体的实体位置3&#xff0c;vuecesium&#xff1a; flyto一个具体的点位置4&#xff0c…

go语言基本排序算法

package mainimport "fmt"func main() {BubbleSort()SelectSort()InsertSort()MergeSort()QuickSort()HeapSort()ShellSort() }//冒泡排序 func BubbleSort() {str : []int{9, 1, 5, 8, 3, 7, 4, 6, 2}for i : 0; i < len(str)-1; i {flag : falsefor j : len(str…

一步完成CalDAV账户同步,日历服务助力钉钉日历日程集中管理

在信息爆炸节奏飞快的今天&#xff0c;高效的管理时间已经成为我们工作和生活中的核心竞争力&#xff0c;复杂纷繁的日程安排&#xff0c;无处不在的提醒需求以及跨设备同步的困扰&#xff0c;这些问题仿佛都在呼唤着一个更智能、更便捷、更可靠的解决方案。 而华为日历App&am…

企业内部机密视频安全保护|如何防止企业内部机密视频泄露?

在企业数字化进程飞速发展的今天&#xff0c;视频内容已成为承载企业内部培训、战略会议、产品机密和核心技术的关键载体。一次意外的泄露&#xff0c;不仅可能导致知识产权流失&#xff0c;更会让企业声誉和市场竞争力遭受重创。面对无孔不入的安全威胁&#xff0c;企业该如何…

C# Deconstruct | 简化元组与对象的数据提取

官方文档&#xff1a;析构元组和其他类型 - C# | Microsoft Learn 标签&#xff1a;Deconstruct、Tuple、record、模式匹配 PS&#xff1a;record相关内容后续还会继续更新&#x1f504; 模式匹配可以查看我的另一篇&#x1f449;模式匹配 目录1. 概述2. 基本用法2.1 元组解…

R 语言 ComplexUpset 包实战:替代 Venn 图的高级集合可视化方案

摘要 在生物信息学、数据挖掘等领域的集合分析中,传统 Venn 图在多维度数据展示时存在信息拥挤、可读性差等问题。本文基于 R 语言的 ComplexUpset 包,以基因表达研究为场景,从包安装、数据准备到可视化实现,完整演示如何制作正刊级别的集合交集图,解决多条件下差异基因(…

​导游|基于SprinBoot+vue的在线预约导游系统

在线预约导游系统 基于SprinBootvue的在线预约导游系统 一、前言 二、系统设计 三、系统功能设计 前台功能实现 后台功能实现 管理员模块实现 导游模块实现 用户模块实现 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&am…

SQL server 异常 出现错误 824

2025-08-27 01:36:37,324 ERROR c.z.i.w.DatabaseUtils [Scheduled-7] Error executeStoredProcedure SQL script: sp_RefreshDWDByDateFive警告: 在 08 27 2025 1:36AM 出现错误 824。请记录该错误和时间&#xff0c;并与您的系统管理员联系。 2025-08-27 01:36:37,332 ERROR …

制造业生产线连贯性动作识别系统开发

制造业生产线连贯性动作识别系统开发 第一部分&#xff1a;项目概述与理论基础 1.1 项目背景与意义 在现代智能制造环境中&#xff0c;尽管自动化程度不断提高&#xff0c;但人工操作仍然在复杂装配任务中扮演着不可替代的角色。研究表明&#xff0c;人机协作被视为打破传统人机…

什么是Jmeter? Jmeter工作原理是什么?

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 第一篇 什么是 JMeter&#xff1f;JMeter 工作原理 1.1 什么是 JMeter Apache JMeter 是 Apache 组织开发的基于 Java 的压力测试工具。用于对软件做压力测试&a…

Linux网络基础1(一)之计算机网络背景

文章目录计算机网络背景网络发展认识 "协议"高小琴例子方言例子计算机网络背景 网络发展 独立模式: 计算机之间相互独立; 网络互联: 多台计算机连接在一起, 完成数据共享; 局域网LAN: 计算机数量更多了, 通过交换机和路由器连接在一起; 广域网WAN: 将远隔千里的计算…

如何在数学建模赛中实现模型创新?

模型创新性在国赛数学建模中&#xff0c;完备性是论文的基本要求&#xff0c;而创新性则是决定论文能否脱颖而出的关键因素。所谓创新&#xff0c;并不仅仅指提出完全新颖的数学理论&#xff0c;而是能够在已有方法的基础上&#xff0c;通过新的问题切入点、假设修正、模型优化…

【重磅发布】flutter_chen_updater-版本升级更新

Flutter Chen Updater 一个功能强大的Flutter应用内更新插件&#xff0c;支持Android APK自动下载、安装和iOS跳转App Store。 ✨ 特性 ✅ 跨平台支持: Android APK自动更新&#xff0c;iOS跳转App Store✅ 智能下载: 支持断点续传、文件校验、多重备用方案✅ 权限管理: 自动处…

docker 1分钟 快速搭建 redis 哨兵集群

使用 docker-compose 1 分钟搭建好 1主2从3哨兵的 redis 哨兵集群 目录结构 redis-sentinel-cluster ├── check_redis.sh ├── docker-compose.yml ├── redis │ └── redis.conf ├── sentinel │ └── sentinel.confdocker-compose.yml 配置 version: 3…

Git与DevOps实战:从版本控制到自动化部署

一、版本控制1.什么是版本控制&#xff1f;版本控制用于高效追踪和管理项目开发中的代码、配置及文档变更历史&#xff0c;确保团队成员始终使用正确版本&#xff0c;并支持版本回溯、差异比较和文件恢复。它能带来以下优势&#xff1a;通过历史记录保障数据安全与完整性&#…

大模型——利用RAG构建智能问答平台实战

利用RAG构建智能问答平台实战 目前公司的智能问答平台利用RAG技术构建,现给大家分享下通RAG技术构建智能问平台的具体流程和原理。 一、什么是RAG RAG是检索增强生成技术(Retrieval-Augmented Generation),目前是构建智能问答的重要技术。RAG相比传统的检索可以可以减少…

flume事务机制详解:保障数据可靠性的核心逻辑

flume事务机制详解&#xff1a;保障数据可靠性的核心逻辑 在数据采集过程中&#xff0c;“不丢数据、不重数据” 是核心需求。Flume 之所以能在分布式环境下保证数据可靠性&#xff0c;关键在于其内置的事务机制。Flume 通过在 “Source → Channel” 和 “Channel → Sink” …

第四十九天(springboot模版注入ThymeleafFreemarkerVelocity)

开发框架-SpringBoot 参考&#xff1a;Spring Boot 中文文档 新建一个spring Boot 项目&#xff0c;修改服务器url为 aliyun.com 不然没有与jdk8版本对应的java 选择一个spring web 库&#xff0c;点击创建即可 来到这个页面点击运行 启动的是8080端口&#xff0c;用127.0.0.1…

Spring MVC 九大组件源码深度剖析(六):HandlerExceptionResolver - 异常处理的艺术

文章目录一、异常处理的核心价值二、核心接口设计三、四大内置实现类源码解析1. ExceptionHandlerExceptionResolver&#xff08;现代异常处理核心&#xff09;2. ResponseStatusExceptionResolver&#xff08;HTTP状态码处理&#xff09;3. DefaultHandlerExceptionResolver&a…

MCP(Model Context Protocol,模型上下文协议)介绍

1. 背景 随着大语言模型&#xff08;LLM, Large Language Model&#xff09;的应用越来越广泛&#xff0c;一个核心问题逐渐凸显&#xff1a; 模型在对话或推理时&#xff0c;往往只能依赖有限上下文窗口。外部工具、知识库、应用接口如何统一接入模型&#xff0c;缺乏标准协议…