3.长度为L的顺序表,编写一个时间复杂度为O(n),空间复杂度为O(1)的算法,该算法删除线性表中所有值为x的元素。
一看就是典型的双指针问题,于是我写代码如下
for(i=0,j=i+1;j<n;i++,j++){
if(a[j]==x){
while(a[j++]==x);
a[++i]=a[j];
}
else if(a[i]==x) a[i]=a[j];
}
//这部分代码是有问题的,如果出现在第一位的话就无法解决了
return i+1;
//正确的方法
int k=0;
for(int i=0;i<n;i++){
if(a[i]!=x) a[k++]=a[i];
}
//同时,利用找x然后删除的办法也是可解的
int k=0;
while(i<n){
if(a[i]==x) k++;
//注意这里,记录之前遇到的相等的数量k
//遇到不等的时候,向后赋值
else a[i-k]=a[i];
i++;
}
题目问的是删除值为x的,我们一般会考虑找x,然后把这些值跳过。
而比较好的办法是利用双指针,然后找不是x的,留下&赋值
8.给定数组A[m+n],要求在不申请额外数组空间的情况下,反转前m和后n个数,并且其内部顺序不可改变.
显然,限制了不申请额外空间就有点棘手了。
可以考虑先将整个数组反转,再将前n个,后m个分别反转
void reverse(vector<int> nums,int left,int right){
if(left>=right || right>nums.size()) return;
int mid=(left+right)/2;
int offset=mid-left;
for(int i=0;i<offset;i++){
swap(nums[left+i],nums[right-i]);
}
}
//于是反转3次即可
reverse(nums,0,m+n+1);
reverse(nums,0,n-1);
reverse(nums,n,m+n-1);
故不要眼高手低地看待任何一题,真正把代码写出来,就会发现自己所写的还有很多缺陷,都一定有可以改进的地方。