剑指 Offer 56 - I. 数组中数字出现的次数
题目描述
一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是\(O(n)\),空间复杂度是\(O(1)\)。
示例1:
输入:nums = [4,1,4,6]
输出:[1,6] 或 [6,1]
示例2:
输入:nums = [1,2,10,4,1,4,3,3]
输出:[2,10] 或 [10,2]
限制:
2 <= nums.length <= 10000
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof
代码实现
class Solution {
public:
vector<int> singleNumbers(vector<int>& nums) {
int diff = 0;
for(auto nt = nums.begin(); nt != nums.end(); nt++)
diff ^= (*nt);
int flag = diff & (-diff);
vector<int> result(2, 0);
for(auto nt = nums.begin(); nt != nums.end(); nt++) {
if((*nt) & flag)
result[0] ^= (*nt);
else
result[1] ^= (*nt);
}
return result;
}
};
思路解析
- 题目的重点是要时间复杂度\(O(n)\),空间复杂度\(O(1)\),考虑位运算的方式;
- 基本的位运算逻辑:
- 使用逻辑异或(\(\oplus\))来区分未成对出现的数字
\(0 \oplus 0 = 0\),\(0 \oplus 1 = 1\); - 逻辑异或(\(\oplus\))运算满足结合律和交换律;
因此,对所有的数字进行异或运算,由于只有两个数字(假设为\(a\)和\(b\))未重复出现,则异或运算的结果是\(a\oplus b\)。
\(a_1 \oplus a_1 \oplus a_2 \oplus a_2 \oplus \cdots a_n \oplus a_n \oplus k = k\)
- 使用逻辑异或(\(\oplus\))来区分未成对出现的数字
- 得到\(a\oplus b\)后,我们需要想一个办法来将
nums分组,考虑所有的数字都可以用二进制表示,则可根据某一位是\(0\)或\(1\)来对nums进行分组,且要保证\(a\)和\(b\)不在同组,采用的分组方式如下:
- 在计算机中,整形数字采用补码的形式表示,正数的补码等于其原码,负数的补码等于其反码+1,以8位
int类型为例:
int s = 8,原码00000100,反码00000100,补码00000100
int s =-8,原码10000100,反码11111011,补码11111100 - 可知:
s & (-s) = 00000100,仅有1位数字为\(1\)(s的最低位\(1\)),且s本身的该位数字也为1,可利用这一特性,对原数组nums进行分类。 - 如何确保\(a\)和\(b\)不在同一分组?
已知\(d = a\oplus b\),则\(d\)的最低位\(1\)一定可以区分\(a\)和\(b\)(异或运算的定义)
则根据\(d\)的某一位\(1\)对原数组进行分组,必定可保证\(a\)和\(b\)不同组。
- 在计算机中,整形数字采用补码的形式表示,正数的补码等于其原码,负数的补码等于其反码+1,以8位
- 分组之后的事情就简单了,由于异或运算满足结合律和交换律,且相同的数字一定被分在的同一组,而\(a\)和\(b\)不同组,对每一组分别进行异或运算,最后两组得到的结果就分别是\(a\)和\(b\)。
剑指 Offer 56 - I. 数组中数字出现的次数的更多相关文章
- 剑指 Offer 56 - II. 数组中数字出现的次数 II + 位运算
剑指 Offer 56 - II. 数组中数字出现的次数 II Offer_56_2 题目详情 解题思路 java代码 package com.walegarrett.offer; /** * @Au ...
- 剑指 Offer 56 - I. 数组中数字出现的次数 + 分组异或
剑指 Offer 56 - I. 数组中数字出现的次数 Offer_56_1 题目描述 解题思路 java代码 /** * 方法一:数位方法 */ class Offer_56_1_2 { publi ...
- 剑指 Offer 56 - II. 数组中数字出现的次数 II
题目描述 在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次.请找出那个只出现一次的数字. 示例1: 输入:nums = [3,4,3,3] 输出:4 示例2: 输入:nums = ...
- 《剑指offer》旋转数组中的最小数字
本题来自<剑指offer> 旋转数组中的最小数字 题目: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例 ...
- 【剑指Offer】旋转数组中的最小数字 解题报告(Python)
[剑指Offer]旋转数组中的最小数字 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://www.nowcoder.com/ta/coding-intervie ...
- 面试题56 - I. 数组中数字出现的次数
面试题56 - I. 数组中数字出现的次数 一个整型数组 nums 里除两个数字之外,其他数字都出现了两次.请写程序找出这两个只出现一次的数字.要求时间复杂度是O(n),空间复杂度是O(1). 示例 ...
- LeetCode 面试题56 - I. 数组中数字出现的次数 | Python
面试题56 - I. 数组中数字出现的次数 题目 一个整型数组 nums 里除两个数字之外,其他数字都出现了两次.请写程序找出这两个只出现一次的数字.要求时间复杂度是O(n),空间复杂度是O(1). ...
- 力扣Leetcode 面试题56 - I. 数组中数字出现的次数
面试题56 - I. 数组中数字出现的次数 一个整型数组 nums 里除两个数字之外,其他数字都出现了两次.请写程序找出这两个只出现一次的数字.要求时间复杂度是O(n),空间复杂度是O(1). 示例 ...
- 【剑指offer】03.数组中重复的数组
剑指 Offer 03. 数组中重复的数字 知识点:数组:哈希表:萝卜占坑思想 题目描述 找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些 ...
随机推荐
- C# ASP 动态添加Html Table行
用JS放法实现以下效果: 前端文件Questionnaire23.aspx: <%@ Page Title="题目" Language="C#" Mast ...
- Elasticsearch+SpringBoot报NoNodeAvailableException解决方案
Elasticsearch整合SpringBoot 首先大家在整合的时候一定要注意版本兼容问题,此问题尤为重要 Elasticsearch简称Es 在使用SpringBoot整合Elasticsear ...
- 提升团队幸福感之:集成 GitLab && JIRA 实现自动化工作流
佛罗伦萨 - 圣母百花圣殿(图) 前言 GitLab 和 Jira 是平时开发过程中使用非常高频的代码管理系统(开发人员)和项目管理系统(项目管理),通过两套系统的协作完成平常大多数的功能开发,但是两 ...
- WeakHashMap的应用场景
WeakHashMap是啥: WeakHashMap和HashMap都是通过"拉链法"实现的散列表.它们的源码绝大部分内容都一样,这里就只是对它们不同的部分就是说明. WeakR ...
- 真正从底层理解 Synchronized 实现原理
实现synchronized的基础有两个:Java 对象头和 Monitor. 在虚拟机规范中定义了对象在内存中的布局,主要由以下 3 部分组成: 对象头 实例数据 对齐填充 而synchronize ...
- linux命令--大小写转换命令
1.tr命令 tr命令转换小写为大写 cat aa.txt | tr a-z A-Z 或者 cat aa.txt | tr [:lower:] [:upper:] tr命令大写转换小写 ...
- Excel提取身份证年龄和性别③
问题场景 从user表中的身份信息中拿到用户的年龄和性别: 以下方法也可适用于提取其他数据,目的在于通过实例操作了解更多函数用法: 以下图中数据都为测试数据,不具备真实性! 场景一 从user表中的1 ...
- latex:公式的上下标
1.行内公式的上下标 在行间公式中,例如\[\max_{i}\]的排版结果是 而在行内公式中,$max_{i}$的排版结果为 ,如果要使其仍在正下方,可插入字体尺寸档次命令 $\displaystyl ...
- CentOS 7环境下大量创建账号的方法
1 一些账号相关的检查工具 1.1 pwck命令 pwck 这个指令在检查 /etc/passwd 这个账号配置文件内的信息,与实际的家目录是否存在等信息,还可以比对 /etc/passwd /etc ...
- Appium学习笔记
1.创建Maven项目 2.POM文件添加java-client依赖坐标 3.修改脚本,执行脚本 UIAutomator2(自动装置引擎) 4723:Appium服务器端口,用来监听脚本发送过来的指令 ...