LeetCode刷题-- 删除元素

LeetCode刷题--删除元素

一、题目

给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并「原地」修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

示例 1:
给定 nums = [3,2,2,3], val = 3,
函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。
你不需要考虑数组中超出新长度后面的元素。

示例 2:
给定 nums = [0,1,2,2,3,0,4,2], val = 2,
函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。

「你不需要考虑数组中超出新长度后面的元素。」

二、题解

本题的关键是通过将要删除的元素的后面的元素向前移动,去覆盖掉要删除的元素,并且将要删除的元素每次都移动在最后面,

有两种解决办法:

第一种是:暴力法 ,通过两个for循环,第1个for循环负责遍历数组,第二个for循环负责更新数组。

第二种是: 双指针法(快慢指针法),通过一个快指针和慢指针在一个for循环下完成两个for循环的工作:

  1. 循环时,快慢指针一起移动
  2. 查到了值,快指针继续移动,慢指针暂停移动一次
  3. 直到快指针指向数组末尾 返回慢指针的位置,就是数组中剩余的元素个数

三、代码

public class _02_移除元素 {

    /**
     * 1. 暴力解法: 时间负载度O(n^2)  空间复杂度O(1)
     * @param nums
     * @param val
     * @return
     */
    public static int removeElement1(int[] nums, int val) {
        int len = nums.length;
        for(int i = 0; i < len; i++){
            if(val == nums[i]){
                for(int j = i+1; j < len; j ++){
                    nums[j-1] = nums[j];
                }
                i--;
                len--;
            }
        }
       return  len;
    }

    /**
     *  双指针法
     *  循环时,快慢指针一起移动
     *  查到了值,快指针继续移动,慢指针暂停移动一次
     *  直到快指针指向数组末尾 返回慢指针的位置。
     * @param nums
     * @param val
     * @return
     */
    public static int removeElement2(int[] nums, int val) {
        int slowIndex = 0;
        for (int fastIndex = 0;  fastIndex < nums.length; fastIndex++) {
            if(val != nums[fastIndex] ){   // 如果不等,才是覆盖,移动,否则只有快指针移动
                nums[slowIndex ++] = nums[fastIndex];
                // 这一步可以分解成两步比较好理解:
                // 1. 先赋值: nums[slowIndex] = nums[fastIndex];
                // 2. 慢指针移动: slowIndex ++;
                // 3. 快指针移动:  for循环中的fastIndex ++
            }
        }
        return slowIndex;
    }
    
    public static void main(String[] args) {
        int [] nums = {3,2,2,1,1,3};
        int val = 3;
        System.out.println(removeElement2(nums, val));    
    }
}

四、时间负载度和空间复杂度

暴力法: 时间复杂度O(n^2) ,空间复杂度O(1)

双指针法:时间复杂度O(n) ,空间复杂度O(1)

原文地址:https://www.cnblogs.com/sinlearn/p/14687100.html