LeetCode刷题之旅(简单-9):移除相同元素

2019年5月19日

目录

题目:移除相同元素

解决方法一:快指针遍历,慢指针赋值索引

性能结果:

算法分析

小结:

解决方法二:比较元素与目标值,一致则与末尾元素交换

性能结果:

算法分析

小结:


题目:移除相同元素

 

解决方法一:快指针遍历,慢指针赋值索引

package leetCode;

/**
 * Date: 2019/5/19 16 :03
 *
 * @author moubin.mo
 */

public class RemovingDuplicateElements {
    public static void main(String [] args){
        int[] nums = {3,2,2,3};
        int val = 3;
        int result = removeElement(nums, val);
        System.out.println("result="+result);
    }

    private static int removeElement(int[] nums, int val) {
        //双指针
        int i = 0;  //快指针
        int j = 0;  //慢指针
        for (;i<nums.length;i++){
            if (nums[i] != val){
                nums[j++] = nums[i];
            }
        }
        return j;
    }

}

性能结果:

算法分析

既然问题要求我们就地删除给定值的所有元素,我们就必须用 O(1)O(1) 的额外空间来处理它。如何解决?我们可以保留两个指针 ii 和 jj,其中 ii 是慢指针,jj 是快指针。

  • 当 nums[j]nums[j] 与给定的值相等时,递增 jj 以跳过该元素。只要 nums[j] \neq valnums[j]​=val,我们就复 nums[j]nums[j] 到 nums[i]nums[i] 并同时递增两个索引。重复这一过程,直到 jj 到达数组的末尾,该数组的新长度为 ii。

复杂度分析

  • 时间复杂度:O(n), 假设数组总共有 n 个元素,i 和 j 至少遍历 2n 步。

  • 空间复杂度:O(1)。

小结:

  • 跟之前的题目解决思路很类似(跳转第8题),使用双指针解法(第8题比较条件是与);
  • 本质:慢指针指向数组开头,快指针作为数组遍历的指针, 指向比较元素;
  • 当快指针指向的数据与val不同,那就赋值给慢指针的位置,然后慢指针自增;

 

解决方法二:比较元素与目标值,一致则与末尾元素交换

package leetCode;

/**
 * Date: 2019/5/19 16 :03
 *
 * @author moubin.mo
 */

public class RemovingDuplicateElements {
    public static void main(String [] args){
        int[] nums = {3,2,2,3};
        int val = 3;
        int result = removeElementV2(nums, val);
        System.out.println("result="+result);
    }


    //当要删除的元素很少时
    //例如,num=[1,2,3,5,4],Val=4num=[1,2,3,5,4],Val=4。之前的算法会对前四个元素做不必要的复制操作。
    //另一个例子是 num=[4,1,2,3,5],Val=4num=[4,1,2,3,5],Val=4。
    // 似乎没有必要将 [1,2,3,5][1,2,3,5] 这几个元素左移一步,因为问题描述中提到元素的顺序可以更改。
    private static int removeElementV2(int[] nums, int val) {
        int i = 0;
        int n = nums.length;
        while (i < n){
            if (nums[i] == val){
                nums[i] = nums[n-1];
                n--;
            }else {
                i++;
            }
        }
        return n;
    }

}

性能结果:

算法分析

  • 当我们遇到 nums[i] = valnums[i]=val 时,我们可以将当前元素与最后一个元素进行交换,并释放最后一个元素。这实际上使数组的大小减少了 1。

  • 请注意,被交换的最后一个元素可能是您想要移除的值。但是不要担心,在下一次迭代中,我们仍然会检查这个元素。

复杂度分析

  • 时间复杂度:O(n)O(n),ii 和 nn 最多遍历 nn 步。在这个方法中,赋值操作的次数等于要删除的元素的数量。因此,如果要移除的元素很少,效率会更高。

  • 空间复杂度:O(1)O(1)。

 

小结:

  • 着实让我大吃一惊,因为这个脑路新奇的解法,很是容易理解:既然有效值都会放到前面的n个位置,那么发现一样的替换为最后一个数值,然后长度值-1就好了;
  • 相比采取贪多囫囵吞枣式做题,不如踏实一步步解决问题,带着思考生活,带着思考工作。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值