目录
第一部分:题目描述
第二部分:题目分析
第三部分:解决方法
3.1思路1: 双指针暴力求解
3.2 思路2:异或运算
第四部分:总结收获
第一部分:题目描述
第二部分:题目分析
由图片分析可得,该题目对算法时间复杂度有一定的要求时间复杂度为O(N),空间复杂度为O(1),这是关键所在,也就是说只能遍历有限次数组,便可以找到那个单独出现的那个数字。
第三部分:解决方法
3.1思路1:双指针暴力求解
定义两个整型变量代表指针,利用双层for循环,外层循环i指向每个元素,内层循环j开始从当前元素的下个位置开始遍历整个数组,寻找是否存在与该元素相同的元素。如果发现了一个相同的元素,计数器加1,否则内层循环继续往下遍历,内层循环结束了但是没有发现相同的元素,那么count一直为0,并且i下标对应的元素a[i]就是单独出现的元素,直接返回即可,当内层循环处理一遍之后,继续处理外层循环的下一个元素i+1,直到把每一个元素都查找过。 但是时间复杂度为:O(n^2)不符合要求。
int singleNumber(int* nums, int len)
{
int i = 0;
//1.针对外层循环每个元素,让内层循环依次与之进行对比
for (; i < len; i++)
{
int count = 0;
//2.内层循环从下一个位置开始,进行比对,同时记录,出现相同的次数
for (int j = i+1; j < len; j++)
{
if (nums[i] == nums[j])
{
count++; //每出现相同的元素,计数器就会加1
}
}
//3.说明没有找到相同的元素,直接返回下标i对应的元素即可
if (count == 0)
{
return nums[i];
}
}
return -1;
}
3.2 思路2:异或运算
异或运算是属于位运算的一种,它是按照位置进行运算的,位与位异或,相同为0,不相同为1,同时,位运算(按位与、按位或、按位异或)是满足交换律和结合律的,因此,位运算它是没有顺序之分的,改变数的运算顺序,并不会改变最后的结果。
在这道题中,解题的思路在于:两个相同的数异或结果一定是0,0和任何数异或是它本身,因此,我们只需从第一个数字开始依次与该数组剩下的每个数字异或,最后留下来的便是所求的数字了。(双爆胎数字异或结果为0,再与其他数异或,并不会改变这个数,最后只剩下单独出现的那个数字,也就是缺失的数字。)
int singleNumber(int* nums, int numsSize)
{
int result = nums[0];
for (int i = 1; i < numsSize; i++)
{
result ^= nums[i];
}
return result;
}
第四部分:总结收获
在数组的遍历中,可以利用整型变量/下标来代替指针,用于标记元素的位置,这道题引入了双指针思想来通过双层for循环暴力求解问题,这是算法题中一个基本的思想,必须熟练掌握。此外,异或运算具有“消消乐”的特点,需要注意。
在后续更新中,我会一直写关于OJ题的题解,有兴趣的小伙伴可以关注作者,和作者讨论其他OJ题目,如果觉得内容不错,请给个一键三连吧,蟹蟹你哟!!!制作不易,如有不正之处敬请指出,感谢大家的来访,UU们的观看是我坚持下去的动力, 在时间的催化剂下,让我们彼此都成为更优秀的人吧!!!