今天带来比较简单的四道OJ题,让我们一起来看一下吧
就是说,在一个数组中,有0~n中的不重复的n-1个数字,让你找到其中的缺失的数字
首先第一个思路,0~n加起来再减去数组中的每一个元素不就是缺失的元素吗
int missingNumber(int* nums, int numsSize){
int num=0;
int n=numsSize;
num=n*(n+1)/2;//计算从0~n的和
for(int i=0;i<numsSize;i++){
num-=nums[i];
}
return num;
}
第二个思路,我们之前在C语言说过^(异或)这个符号,相同的数异或为0,0和任意数异或都等于任意数,于是我们就可以想到让0~n的数和数组中的数全都异或一遍,这样出现两遍的数就异或为了0,最后就只剩异或了一遍的数
int missingNumber(int* nums, int numsSize){
int num=0;
for(int i=0;i<=numsSize;i++){//和0~n之间的数异或
num^=i;
}
for(int j=0;j<numsSize;j++){//和数组中的数异或
num^=nums[j];
}
return num;
}
就是说,给一个数组,删除掉所有等于val的元素,后面的元素往前移,但是有规定,不能额外创建数组,也就是空间复杂度为O(1)
这就是一个典型的双指针问题,我们可以定义两个指针,一个负责检测是否为val,一个负责要记录下一个写入的位置
int removeElement(int* nums, int numsSize, int val){
int p1=0;
int p2=0;
for(p1=0;p1<numsSize;p1++){
if(nums[p1]!=val){
nums[p2]=nums[p1];
p2++;
}
}
return p2;
}
当然我们也可以前面定义一个,后面定义一个,都是可以的
int removeElement(int* nums, int numsSize, int val){
int start=0;
int end=numsSize;
while(start<end){
if(nums[start]==val){
nums[start]=nums[end-1];
end--;
}
else{
start++;
}
}
return start;
}
这里要注意,为什么end也就是后面的指针开始等于numsSize,并且下面一直用它的值减一去判断,其实这样是合理的且巧妙的,因为end如果就从numsSize-1开始并且用它自己的值去判断,会出现一种情况就是start和end同时指向一个元素且这个元素不能被删,并且这时进不去循环了,最后就会少算一个,这样是一种解决办法,另一种经过分析也知道了,就让等于的之后进去嘛,改一下程序也是可以的:
int removeElement(int* nums, int numsSize, int val){
int start=0;
int end=numsSize-1;
while(start<=end){
if(nums[start]==val){
nums[start]=nums[end];
end--;
}
else{
start++;
}
}
return start;
}
就是说,删除一个数后面与这个数相同的数
思路还是两个指针,一个负责遍历,另一个负责记录下一个数要存放的位置,正好这两个位置的值可以进行比较
int removeDuplicates(int* nums, int numsSize){
int count=0;
for(int i=1;i<numsSize;i++){
if(nums[count]!=nums[i]){
count++;
nums[count]=nums[i];
}
}
count++;
return count;
}
这是用了两个指针,思路确实不容易想到我们把它们的功能分开,因为如果是不同或者相同的话,它们都是挨着的嘛,所以创建三个指针,一个负责记录要写下的位置,两个挨着的指针负责识别是否相同
int removeDuplicates(int* nums, int numsSize){
int n=1;
int s1=0;
int s2=1;
while(s2<numsSize){
if(nums[s1]!=nums[s2]){
nums[n]=nums[s2];
n++;
}
s1++;
s2++;
}
return n;
}
就是给定了两个有序数组,其中数组一足够大,也就是把数组二并入到数组一中,从而使最后有序
因为最后要把所有数据放到数组一中,所以不能从前往后进行赋值,要从后往前以保证不会丢失数据
oid merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n){
int s1=m-1;
int s2=n-1;
int a=nums1Size-1;
while(s1>=0&&s2>=0){
if(nums1[s1]>nums2[s2]){
nums1[a]=nums1[s1];
a--;
s1--;
}
else{
nums1[a]=nums2[s2];
a--;
s2--;
}
}
while(s2>=0){
nums1[a]=nums2[s2];
a--;
s2--;
}
}