LeetCode27-移除元素

题目描述

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

我的题解

基本思路是遍历数组,遇到和val相等的,就使用‘最后一个’赋值。最后就会去掉所有的val等值元素。

    public int removeElement(int[] nums, int val) {
        int len = nums.length;
        int delCount=0;
        for(int i=0;i<len-delCount;i++){
            if(val==nums[i]){
                nums[i]=nums[len-delCount-1];//把和val等值的覆盖掉
                delCount++;//删除值的数量+1
                if(nums[i]==val) i--; //如果新值还是和val相等,i--抵消掉for的i++,原地再次替换掉。
            }
        }
        return len-delCount;
    }

本来以为这题很简单,上面的就已经击败100%的用户了
没想到
还有更好的写法

其他题解

    public int removeElement(int[] nums, int val) {
        int k =0;
        for(int i=0;i<nums.length;i++){
            if(val!=nums[i]){
                nums[k++]=nums[i];
            }
        }
        return k;
    }

这个算法更巧妙
和前面从后取值覆盖前值的思维不同,这里是值前移的思维(k<=i始终成立,从而可以前移)
代码更加简洁
但是仔细思考下,这里每一个合法的值都会做一次移动,对于只有个别值和val相同的情况,做了太多次的无效移动,实则不好。
对于大多数值都需要去除的情况,则减少了数组赋值的次数。

于是:
这两种解法实则是等价的,在不同的情况下有不同的效率。

posted @ 2020-03-16 00:08  Edwin_Xu  阅读(83)  评论(1编辑  收藏  举报