zoukankan      html  css  js  c++  java
  • 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)

  • 相关阅读:
    激活第一个CPU
    每CPU变量
    在 Vue中使用layui日历控件,标注重要日子
    手机号,银行卡断开方式
    下载文件流
    使用class关键字创建类组件、props参数
    class继承关键字extends和super
    用于判断文件是已什么结尾的
    flex一些属性
    类组件
  • 原文地址:https://www.cnblogs.com/sinlearn/p/14687100.html
Copyright © 2011-2022 走看看