题目:找单身狗(简单)
给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:
// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝 int len = removeDuplicates(nums); // 在函数里修改输入数组对于调用者是可见的。 // 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。 for (int i = 0; i < len; i++) { print(nums[i]); }
思路要点:
操作符^:两个相同的数异或为0;0异或任何数为任何数
参考代码:
int missingNumber(int* nums, int numsSize){ //记录异或的结果 int x=0; int i; for(i=0;i<=numsSize;i++) { //先异或一遍完整的数据 x^=i; if(i<numsSize) //异或数组中的数 x^=nums[i]; } //得到的结果为缺失的数 return x; }
执行结果:
题目:找单身狗(复杂)
一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
示例:
- 思考要点:
将两个单身狗分开来异或,单独得到两个单身狗
- 参考代码:
1.int* singleNumbers(int* nums, int numsSize, int* returnSize){ //动态开辟数组 int* arr=(int*)malloc(2*sizeof(int)); //记录异或结果 int eor=0; //得到的结果为两个单身狗异或的结果 for(int i=0;i<numsSize;i++) { eor^=nums[i]; } //两个单身狗必定有个二进制位置数据不一,以此作为分治的判断依据 //找到异或结果最右边位1的位置 int right=eor&(~eor+1); //创建两个数依据 int one=0;int two=0; for(int i=0;i<numsSize;i++) { //&right结果不为0则在最右边为1的位置上为该数据也为1 if(right&nums[i]) { //得到的结果为那只单身狗 one^=nums[i]; } //为0则在最右边为1的位置上为该数据为0 else { two^=nums[i]; } } arr[0]=one; arr[1]=two; *returnSize=2; return arr; }
执行结果: