这是一系列位运算的题目,本文将由浅入深,先从最简单的问题开始:

问题1:

一个数组中只有一个数字出现过1次,其余数字都出现过两次,请找到那个只出现1次的数字。要求时间复杂度是 \(O(n)\),空间复杂度是 \(O(1)\)。

解法:

考虑到位运算中的异或运算,一个数字和它自己做异或,结果为0。所以只需要遍历整个数组,挨个异或,最后得到的结果就是那个只出现1次的数字。

class Solution {
public:
vector<int> singleNumbers(vector<int>& nums) {
int res = 0;
for (auto num : nums) {
res ^= num;
}
return res;
}
};

问题2:

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

解法:

与问题 1 的区别在于,这个问题中有两个出现次数为 1 的数字。可以将数组分成两个子数组,每个子数组中各含一个只出现 1 次的数字。具体做法为:

  • 对所有数字求异或,得到的结果即为 res
  • 保留 res 中的一个为 1 的数位,其余数位都变成 0,可以用 res & -res 保留最低位的 1,记为 div
  • 将数组中的每个数字和 div 做异或,按照结果为0或1分成2组,这样相同的数字都会被分到同一组,而那两个只出现 1 次的数字会被分到不同的组
  • 按组再做异或,同问题1,得到答案。

实际操作中不需要真正分组,只需要用两个变量 ab 记录两个组的异或值即可。

class Solution {
public:
vector<int> singleNumbers(vector<int>& nums) {
int res = 0;
for (auto num : nums) {
res ^= num;
}
int a = 0, b = 0;
int div = res & -res;
for (auto num : nums) {
if (div & num) {
a ^= num;
} else {
b ^= num;
}
}
return {a, b};
}
};

问题3:

在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。

解法:

参考:K神的题解

如下图所示,考虑数字的二进制形式,对于出现三次的数字,各二进制位 出现的次数都是 3 的倍数。因此,统计所有数字的各二进制位中 1 的出现次数,并对 3 求余,结果则为只出现一次的数字。

class Solution {
public:
int singleNumber(vector<int>& nums) {
vector<int> digit(32); // 记录所有数字每个数位上1出现的次数之和
for (auto num : nums) { // 遍历每个数字
for (int i = 0; i < 32; i++) { // 遍历每个数位
digit[i] += num & 1; // num & 1 得到该数位是否为1
num >>= 1; // 获得下一个数位
}
}
int ans = 0, m = 3;
for (int i = 31; i >= 0; i--) {
//倒着遍历digigt数组,因为高数位在大下标位置
ans <<= 1; // ans左移1位
ans |= digit[31 - i] % m; // 每个数位对m取余后再和ans做或运算
}
return ans;
}
};

上面的代码只需要修改求余数值 \(m\) ,即可实现解决除了一个数字之外,其余数字都出现 \(m\) 次的通用问题。

【位运算】剑指offer 56. 数组中数字出现的次数的更多相关文章

  1. [剑指Offer]56-数组中数字出现的次数(位运算)

    题目一 数组中只出现一次的数字 题目 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字 题解 异或. 先考虑:数组中只有一个数字只出现了一次,其他数字都出现了 ...

  2. 剑指offer——62数组种数字出现的次数

    题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 题解: 我们想到异或运算的一个性质:任何一个数字异或它自己都等于0.也就是说,如果我们从头到尾依 ...

  3. 【剑指Offer】数组中只出现一次的数字 解题报告(Python)

    [剑指Offer]数组中只出现一次的数字 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-intervie ...

  4. 剑指Offer:数组中出现次数超过一半的数字【39】

    剑指Offer:数组中出现次数超过一半的数字[39] 题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如,输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于这 ...

  5. 《剑指offer》数组中只出现一次的数字

    本题来自<剑指offer> 数组中只出现一次的数字 题目: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. 思路: 思路一:在<剑指of ...

  6. 剑指 Offer 51. 数组中的逆序对 + 归并排序 + 树状数组

    剑指 Offer 51. 数组中的逆序对 Offer_51 题目描述 方法一:暴力法(双层循环,超时) package com.walegarrett.offer; /** * @Author Wal ...

  7. 剑指 Offer 39. 数组中出现次数超过一半的数字 + 摩尔投票法

    剑指 Offer 39. 数组中出现次数超过一半的数字 Offer_39 题目描述 方法一:使用map存储数字出现的次数 public class Offer_39 { public int majo ...

  8. 剑指 Offer 03. 数组中重复的数字

    剑指 Offer 03. 数组中重复的数字 找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知 ...

  9. 菜鸟刷题路:剑指 Offer 03. 数组中重复的数字

    剑指 Offer 03. 数组中重复的数字 哈希表/set class Solution { public int findRepeatNumber(int[] nums) { HashSet< ...

随机推荐

  1. elasticsearch 是如何实现 master 选举的 ?

    想了解 ES 集群的底层原理,不再只关注业务层面了. 前置前提: 1.只有候选主节点(master:true)的节点才能成为主节点. 2.最小主节点数(min_master_nodes)的目的是防止脑 ...

  2. Zookeeper 的典型应用场景 ?

    Zookeeper 是一个典型的发布/订阅模式的分布式数据管理与协调框架,开发人员 可以使用它来进行分布式数据的发布和订阅. 通过对 Zookeeper 中丰富的数据节点进行交叉使用,配合 Watch ...

  3. 机器学习综合库gensim 简单搞定文本相似度

    不废话直接代码吧 # 1.模块导入 import jieba import gensim from gensim import corpora from gensim import models fr ...

  4. mysql8.0时区问题

    今天在mysql新增一条数据的时候,发现时间类型的字段比起现在少了8个小时,查了资料才发现,这个是MySQL8.0出现的问题,讲下解决方法. 1.在java项目中application.yml文件中的 ...

  5. 自动驾驶运动规划-Reeds Shepp曲线

    自动驾驶运动规划-Reeds Shepp曲线 相比于Dubins Car只允许车辆向前运动,Reeds Shepp Car既允许车辆向前运动,也允许车辆向后运动. Reeds Shepp Car运动规 ...

  6. Linux基础学习 | 目录及文件

    一.目录结构 Linux目录采用树形结构,以根目录/向下延伸呈一个倒置的树的形状. 每个目录下都有其相对应的子目录,而子目录中又有其子目录的存在,就像一棵树的树枝分叉,所有的目录层次结构分明,每个目录 ...

  7. MATLAB与Carsim联合仿真时提示matlab not found的解决方法(CarSim在联合仿真时提示找不到MATLAB的解决方法)

    CarSim8.02并没有提供选择联合仿真的MATLAB/Simulink的版本的功能,CarSim总是与最后安装的MATLAB/Simulink进行联合仿真,如果安装有多个matlab版本则只打开最 ...

  8. 数字电路基础知识——组合逻辑电路(数据选择器MUX、多路复用器)

    转自:https://blog.csdn.net/vivid117/article/details/100747939 数字电路基础知识--组合逻辑电路(数据选择器MUX.也即多路复用器)本次介绍数据 ...

  9. 【转载】10个Web3D可视化精彩案例

    1.化学元素周期表 六种排列方式,炫酷动画效果,TWaver 3D轻松实现. 演示地址:http://demo.servasoft.com/che... 2.DNA螺旋图 DNA3D模型,包含几千个球 ...

  10. 从零开始:微信小程序新手入门宝典《一》

    为了方便大家了解并入门微信小程序,我将一些可能会需要的知识,列在这里,让大家方便的从零开始学习: 一:微信小程序的特点 张小龙:张小龙全面阐述小程序,推荐通读此文: 小程序是一种不需要下载.安装即可使 ...