数组中数字出现的次数
一个整型数组 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
分组异或:
- 先将所有元素做异或,结果nor为两个只出现一次元素的异或(必不为0)
- 选择nor二进制位为1的位置pos(为1说明两个只出现一次元素对应位置不同,可根据这个位置将两个元素分开)
- 对于出现两次的元素,根据元素对应pos是否为1也可以分为两组,相同的元素必出现在同一组中
- 对两组元素分别做异或可求出只出现一次的元素
public int[] singleNumbers(int[] nums) {
int[] ans = new int[2];
int nor = 0;
for (int num : nums) {
nor ^= num;
}
int divNum = 1;
while ((divNum & nor) == 0) {//向前找到第一个为1的位置
divNum <<= 1;
}
for (int num : nums) {
if ((num & divNum) == 0) {
ans[0] ^= num;
} else {
ans[1] ^= num;
}
}
return ans;
}
数组中数字出现的次数 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
例子:
nums = [2,5,2,2]
2 = 0 0 1 0
5 = 0 1 0 1
2 = 0 0 1 0
2 = 0 0 1 0
对应位置的二进制和为count = 0 1 3 1
coun%3 = 0 1 0 1 = 5
可解决一个数字出现一次,其余数字出现m次的通用问题
public int singleNumber(int[] nums) {
int[] count = new int[32];
for (int num : nums) {
int i = 0;
while (num != 0) {
count[i++] += num & 1;
num >>>= 1;
}
}
int ans = 0;
int m = 3;
for (int i = count.length - 1; i >= 0; i--) {
ans = (ans << 1) + count[i] % m;
}
return ans;
}