移除元素-双指针法

移除元素

移除元素

  1. 暴力解法: 1)遍历所有元素 2)遇到符合条件元素进行移除, 通过for循环将后序元素向前覆盖。

双指针可以通过一次for循环完成两个for循环的任务, 有快慢指针(两个指针从索引0开始移动,但是移动速度不同)for循环实现, 首尾指针(一个指针从0往后移动一个指针从后往0移动)while实现

  1. 双指针(快慢指针): 快指针正常遍历nums, 慢指针记录不等于val值的位置, 相当于遍历一遍将不等于val的值往前移动, 而慢指针最后指向的位置就是最后数组大小
  2. 双指针(首尾指针): 首指针遍历作用, 遇到等于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;
    }

}
posted @ 2022-02-12 18:33  -Rocky-  阅读(66)  评论(0编辑  收藏  举报