移除数组中的指定值

Input:数组nums,需要移除的元素val
Output:原数组nums以及移除val后的数组长度

  这是LeetCode上难度为简单的题,最近做的时候,首先想的方法就是,判断当前有多少个连续的值均为val,然后把后面的元素全部前移,如下所示。

public int removeElement(int[] nums, int val) {
		//首先判断数组是否为空
        if(nums == null || nums.length == 0) return 0;
        int count = 0;
        for(int i = 0;i<nums.length;i++){
            if(nums[i] == val){
                int bias = 0;
                for(int j = i;j<nums.length;j++){
                    if(nums[j] != val)  break;
                    bias++;
                }
                shiftLeft(nums, i, bias, val);
            }
        }
        //此时数组后部分全为元素val,需要遍历一次然后计数
        for(;count<nums.length;count++){
            if(nums[count] == val)  break;
        }
        return count;
    }
    /* 将start+bias开始的值全部前移bias个位置*/
    private void shiftLeft(int[] nums, int start, int bias, int val){
        for(int i = start+bias;i<nums.length;i++){
            nums[i-bias] = nums[i];
            //表明该位置的值无效,所以重新赋值为val
            nums[i] = val;
        }
    }

然后一提交发现自己10个月前已经做过了! = _ =,而且当时使用的是一个双指针,代码更加通俗易懂,和官方解答是一样的。平常还是得多学习总结,继续努力才行,唉。。。
(仅遍历一次,时间复杂度为O(n),空间复杂度为O(1))

public int removeElement(int[] nums, int val) {
        if(nums == null || nums.length == 0) return 0;
        //记录当前元素个数
        int count = 0;
        for(int i = count;i<nums.length;i++){
            if(nums[i] != val){
                nums[count++] = nums[i];
            }
        }
        return count;
    }

然后是又刷了一道类似的题,需要移除数组中重复的元素,也就是每个元素只保留一次

Input:数组nums
Output:原数组nums以及移除val后的数组长度

仍然是双指针的思路,相比于前一题,这次不是往后移一个位置就行了,而是平移至另一个不等的元素,所以使用了一个while循环代替了原来的i++。

public int removeDuplicates(int[] nums) {
		//count记录当前元素个数
        int count = 0;
        for(int i = count;i<nums.length;){
            int val = nums[i];
            nums[count++] = val;
            while(i < nums.length){
                if(nums[i] != val){
                    break;
                }
                i++;
            }
        }
        return count;
    }