移除元素-双指针法
移除元素
移除元素
- 暴力解法: 1)遍历所有元素 2)遇到符合条件元素进行移除, 通过for循环将后序元素向前覆盖。
双指针可以通过一次for循环完成两个for循环的任务, 有快慢指针(两个指针从索引0开始移动,但是移动速度不同)for循环实现, 首尾指针(一个指针从0往后移动一个指针从后往0移动)while实现
- 双指针(快慢指针): 快指针正常遍历nums, 慢指针记录不等于val值的位置, 相当于遍历一遍将不等于val的值往前移动, 而慢指针最后指向的位置就是最后数组大小
- 双指针(首尾指针): 首指针遍历作用, 遇到等于val值, 将其与尾指针元素互换, 尾指针前移,最终首尾相遇结束。
题解
static class Solution {
// 暴力解法:双循环,一个循环遍历数组, 一个循环后向前覆盖移除元素。
public int removeElement1(int[] nums, int val) {
int size = nums.length - 1;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == val) {
for (int j = i + 1; j < nums.length; j++) {
nums[j - 1] = nums[j];
}
i--; //向前覆盖了一个元素,索引向前移动一位
size--;
}
}
return size;
}
public int removeElement2(int[] nums, int val) {
// 双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。保证元素相对位置不变
// 时间复杂度:O(n)
// 空间复杂度:O(1)
int slowIndex = 0;
for (int fastIndex = 0; fastIndex < nums.length; fastIndex++) {
if (nums[fastIndex] != val) {
nums[slowIndex++] = nums[fastIndex];
}
}
return slowIndex;
}
public int removeElement3(int[] nums, int val) {
// 双指针法(首尾指针):不保证元素相对位置不变
// 0 1 2 3 4
int leftIndex = 0, rightIndex = nums.length - 1;
while (leftIndex <= rightIndex) {
//遍历左指针
if (nums[leftIndex] == val) {
nums[leftIndex] = nums[rightIndex];
rightIndex--;
} else {
leftIndex++;
}
}
return leftIndex;
}
}