使用快慢指针,保持原有的元素顺序
慢指针指向当前准备赋值的位置,快指针去遍历所有的元素
function removeElement(nums: number[], val: number): number {
let slow = 0 // 指向当前准备赋值的位置
let fast = 0 // 指向当前检查的位置
while (fast < nums.length) {
// 当不等于 val 的时候可以对 slow 进行赋值
if (nums[fast] !== val) {
nums[slow] = nums[fast]
slow += 1 // 向后移动一位,同时也是当前状态下的 len
}
// 检查下一个
fast += 1
}
return slow
}
使用对撞指针,不保持原有的元素顺序,性能优于双指针 1
left 和 slow 用处一样,但是 right 指针从末尾往前面遍历,相遇的时候即处理完了
function removeElement(nums: number[], val: number): number {
// 指向当前准备检查的位置
// 因为检查通过后会 +1 再次检查下一位
// 所以每一轮结束的时候 left 就是当前状态下的 len
let left = 0
let right = nums.length - 1 // 指向当前检查的位置
// left <= right 的时候需要处理
// 因为 right 从 nums.length - 1 开始处理
// 所以需要处理完当前位置的 right
// 如果从 nums.length 开始处理的话,那么使用 left < right 即可
// 不过这种情况下赋值的时候应该赋值 right - 1 的值
while (left <= right) {
// 如果 left === val
// 使用 right 替代,然后再次判断是否满足条件
if (nums[left] === val) {
nums[left] = nums[right]
right -= 1 // 向前移动一位,接着判断 left
} else {
// left !== val
// 检查下一个
left += 1
}
}
return left
}
使用对撞指针
和双指针 2 的区别是