数据结构(七十六)
学习数据结构与算法过程中的心得体会以及知识点的整理,方便我自己查找,也希望可以和大家一起交流。
—— 数组中数字出现的次数① ——
1.题目描述
一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
示例
输入:
nums = [4,1,4,6]
输出:
[1,6] 或 [6,1]
输入:
nums = [1,2,10,4,1,4,3,3]
输出:
[2,10] 或 [10,2]
2.代码
c
int *singleNumbers(int *nums, int numsSize, int *returnSize){
int *ret = (int *)malloc(sizeof(int) * 2);
int x = 0,i = 0,k = 1;
for (; i < numsSize; i++)
x ^= nums[i]; // 异或运算,取得两个不同值的异或结果
// 找到不同值两数的右侧第一个不同位k (划分数组)
while ((x & k) == 0)
k <<= 1;
// 利用k位进行与运算将数组划分为两部分,两个不同值分别位于这两部分数组中
// 对两部分分别进行异或运算,利用异或特性即可求得每部分中那个不同值
ret[0] = 0,
ret[1] = 0;
for (i = 0; i < numsSize; i++){
if ((nums[i] & k) == 0)
ret[0] ^= nums[i];
else
ret[1] ^= nums[i];
}
*returnSize = 2;
return ret;
}
异或运算特点: 1. x^0 = x;
2. x^x = 0;
因此异或满足以下规律:
a^b^c^b = a^c
a^b^b = a^(b^b) = a^0 = a
此题的关键是两个不同数分配两个组里,再各组异或即得结果。那么如何划分?可以全组异或,最终得到两个不同值的异或结果,可以按位与,找出他们第一个不同位k,接着以此划分数组,再分别全组异或求得结果。