Nameless Site

But one day, you will stand before its decrepit gate,without really knowing why.

0%

移除元素

来源Leetcode第27题移除元素

给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

示例 1:

给定 nums = [3,2,2,3], val = 3,

函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。
你不需要考虑数组中超出新长度后面的元素。

双指针

拿到这题的时候第一想法就是头尾双指针,但是不知道这样写为什么会出问题,太蔡了,一时找不到问题出错点。后面重写时又出问题了,TLE,T T,也没搞懂为什么会超时,太难了,明明是和之前删除重复元素差不多的写法。
先附上AC的代码吧:

1
2
3
4
5
6
7
8
9
10
int removeElement(int* nums, int numsSize, int val){
int i = 0;
for (int j = 0; j < numsSize ; j++) {
if (nums[j] != val) {
nums[i] = nums[j];
i++;
}
}
return i;
}

至于自己写问题的代码,先附上吧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include<stdio.h>

int removeElement(int* nums, int numsSize, int val){
if(numsSize == 0) return 0;
int i = 0;
int j = numsSize - 1;
while(i < j){
while(nums[i] != val && i < j){
i++;
printf("i = %d nums[%d] = %d \n",i,i,nums[i]);
}
// 从左向右找到等于 val 的位置
while(nums[j] == val && i < j){
j--;
}
// 从右向左找到不等于 val 的位置
nums[i] = nums[j];
j--;
}
//此时i == j ,但是不知道nums[i] 的值是否等于val
printf("i = %d\n",i);
return i + nums[i] != val;
}

int main(void) {
int nums[4];
nums[0] = 1;
nums[1] = 2;
nums[2] = 3;
nums[3] = 2;
int k = removeElement(nums,4,2);
printf("k = %d\n",k);
return 0;
}

执行完成,耗时:4 ms
i = 1 nums[1] = 2
i = 1
k = 1

有点迷,这结果。

找到结果了,优先级的问题, != 的优先级比 ‘+’ 低,修改成了 return i + (nums[i] != val); 就过了

正确的应该是:

1
return i + (nums[i] != val);