本文已参与「新人创作礼」活动,一起开启掘金创作之路
目录
题目:找单身狗(简单)
力扣链接:面试题 17.04. 消失的数字
给你一个有序数组 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;
}
- 执行结果:
题目:找单身狗(复杂)
力扣链接:剑指 Offer 56 - I. 数组中数字出现的次数
一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(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;
}
执行结果: