代码链接
https://leetcode-cn.com/problems/remove-element/
采取双指针获取需要的元素,代码如下
class Solution {
public int removeElement(int[] nums, int val) {
int fastIndex = 0;
int slowIndex;
for(slowIndex = 0; fastIndex < nums.length; fastIndex++){
//如果符合条件
if(nums[fastIndex] != val){
//slowIndex++
nums[slowIndex] = nums[fastIndex];
slowIndex++;
}
}
return slowIndex;
}
}
设置一个慢指针,一个快指针,使用快指针遍历数组,当nums[fastIndex] != val,慢指针赋值并加一,最后返回数组。
上述方法使用fastIndex遍历了整个数组,时间复杂度是O(n),其实不算有灵魂的双指针,在最坏情况下,左右指针都遍历了数组,而且所有元素都重新赋值了一遍,下面的方法有一些小优化。
优化代码:
class Solution {
public int removeElement(int[] nums, int val) {
int right = nums.length - 1;
int left = 0;
//左右指针往中间收拢
while (left <= right) {
//右边元素不合法,右指针左移
if(nums[right] == val) {
right--;
//右边元素合法,开始扫左边的指针,如果不合法,直接将右指针的元素赋值到左指针上,继续第一步操作
} else if (nums[left] == val){
nums[left] = nums[right];
right--;
//右边元素合法,左边也合法,左指针直接左移
} else if (nums[left] != val){
left++;
}
}
return left;
}
}
这个优化代码的时间复杂度也是O(n),但是它在最坏情况下,虽然左右指针合起来会扫一遍数组,但是不会产生赋值操作,所以,优化代码相当于减少了第三个条件语句中本该有的赋值操作。