剑指 Offer 56 - II. 数组中数字出现的次数 II
题目描述
在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。
示例1:
输入:nums = [3,4,3,3]
输出:4
示例2:
输入:nums = [9,1,7,9,7,9,7]
输出:1
限制:
1 <= nums.length <= 10000
1 <= nums[i] < 2^31
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-ii-lcof
方法一:map
class Solution {
public:
int singleNumber(vector<int>& nums) {
map<int, int> nums_map;
for(int num : nums)
nums_map[num]++;
for(auto &key : nums_map)
if(key.second == 1)
return key.first;
return 0;
}
};
这个方法不用多说,时间复杂度和空间复杂度均为\(O(n)\)。
方法二:位运算
基本思路:int值为32位,由于仅有一个数字只出现了1次,其余数字均出现了3次,统计每一位上1出现的次数,并对3求余,可得目标数字的二进制表示。
class Solution {
public:
int singleNumber(vector<int>& nums) {
if(nums.empty()) return 0;
int result = 0;
// 对32位分别统计1出现的次数
for(int i = 0; i < 32; i++) {
int count = 0;
int index = 1 << i;
// 遍历数组中的每个数字,统计第i位上是否为1
for(int num : nums) {
if((index & num) != 0)
count++;
}
// 若count对3求余结果为1,则目标数字的该位为1,使用按位或运算记入result
if(count % 3 == 1)
result |= index;
}
return result;
}
};
时间复杂度\(O(n)\),空间复杂度\(O(1)\)。
方法三:位运算进阶
方法二在时间复杂度和空间复杂度上都已经很好了,但还有加速的空间,由于方法二中对每一个数字都需要进行32次统计,则时间复杂度\(O(n)\)有常系数32,思考办法将常系数32降低。
- 我们的目的没有改变,仍然是统计第\(i\)位上1出现的次数\(n_i\),准确的说是统计\((n_i\% 3)\)。
- 每一位上1出现的次数对3的余数可以表示为0,1,2三种情况,但是3中情况无法使用一位二进制数字来表示,因此我们需要扩充至两位二进制数字
00 01 10,最后得到64位的结果的形式如下:
00 01 10 ... 00 10 ... low表示低位,high表示高位,真值表如下:
| high | low | digit | high | low |
|---|---|---|---|---|
| → | ||||
| 0 | 0 | 0 | 0 | 0 |
| 0 | 1 | 0 | 0 | 1 |
| 1 | 0 | 0 | 1 | 0 |
| 0 | 0 | 1 | 0 | 1 |
| 0 | 1 | 1 | 1 | 0 |
| 1 | 0 | 1 | 0 | 0 |
- 低位的求值方法为:
if(high == 0)
if(digit == 0)
low = 0;
else
low = 1;
else
low = 0;
使用异或运算表达:
if(high == 0)
low = (low ^ digit);
else
low = 0;
稍加整理:
low = (low ^ digit) & (~high)
- 高位的求值方法为:
在计算高位之前,要考虑到此时的低位已经是经过运算之后的新的低位。
if(low == 0)
if(digit == 0) // 对应真值表第三行和第五行
high = high;
else // 对应真值表第七行和第八行
high = ~high;
else // 对应真值表第四行和第六行
high == 0;
使用异或运算表达:
if(low == 0)
high = (high ^ digit);
else
high = 0;
稍加整理:
high = (high ^ digit) & (~low);
最终代码实现如下:
class Solution {
public:
int singleNumber(vector<int>& nums) {
int low = 0;
int high = 0;
for(int num : nums) {
low = (low ^ num) & (~high);
high = (high ^ num) & (~low);
}
return low;
}
};
时间复杂度\(O(n)\),空间复杂度\(O(1)\)。
剑指 Offer 56 - II. 数组中数字出现的次数 II的更多相关文章
- 剑指 Offer 56 - I. 数组中数字出现的次数 + 分组异或
剑指 Offer 56 - I. 数组中数字出现的次数 Offer_56_1 题目描述 解题思路 java代码 /** * 方法一:数位方法 */ class Offer_56_1_2 { publi ...
- 剑指 Offer 56 - I. 数组中数字出现的次数
题目描述 一个整型数组 nums 里除两个数字之外,其他数字都出现了两次.请写程序找出这两个只出现一次的数字.要求时间复杂度是\(O(n)\),空间复杂度是\(O(1)\). 示例1: 输入:nums ...
- 剑指 Offer 56 - II. 数组中数字出现的次数 II + 位运算
剑指 Offer 56 - II. 数组中数字出现的次数 II Offer_56_2 题目详情 解题思路 java代码 package com.walegarrett.offer; /** * @Au ...
- 《剑指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). 示例 ...
随机推荐
- Flutter 入门
- Java基础—控制流程语句(条件语句与循环结构)
与任何程序设计语言一样,Java使用条件语句和循环结构确定控制流程.Java的控制流程结构与C和C++的控制流程机构一样,只有很少的例外情况.没有goto语句,但break语句可以带标签,可以利用它实 ...
- C#LeetCode刷题之#728-自除数(Self Dividing Numbers)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3889 访问. 自除数 是指可以被它包含的每一位数除尽的数. 例如 ...
- C#LeetCode刷题之#168-Excel表列名称(Excel Sheet Column Title)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3850 访问. 给定一个正整数,返回它在 Excel 表中相对应的 ...
- SpringSecurity权限管理系统实战—一、项目简介和开发环境准备
目录 SpringSecurity权限管理系统实战-一.项目简介和开发环境准备 SpringSecurity权限管理系统实战-二.日志.接口文档等实现 SpringSecurity权限管理系统实战-三 ...
- python利用爬虫获取百度翻译,爱词霸翻译结果,制作翻译小工具
先看效果展示(仅作学习使用,非商业) 效果图是采用的 爱词霸 翻译,百度翻译 也实现了,只不过被注释了. 学计算机很多时候碰到生词,每次打开手机/浏览器翻译总觉得很麻烦,就想着自己写一个软件,自己去实 ...
- 编译原理根据项目集规范族构造LR(0)分析表
转载于https://blog.csdn.net/Johan_Joe_King/article/details/79058597?utm_medium=distribute.pc_relevant.n ...
- 如何理解算法时间复杂度的表示法O(n²)、O(n)、O(1)、O(nlogn)等?
先从 来说,理论上哈希表就是O(1).因为哈希表是通过哈希函数来映射的,所以拿到一个关键字,用哈希函数转换一下,就可以直接从表中取出对应的值.和现存数据有多少毫无关系,故而每次执行该操作只需要恒定的时 ...
- Magento 2 Factory Objects
In object oriented programming, a factory method is a method that’s used to instantiate an object. F ...
- Linux用户和组密令大全
本文总结了Linux添加或者删除用户和用户组时常用的一些命令和参数. 1.建用户: adduser phpq passwd phpq ...