1. 有序数组消除冗余

有序数组消除冗余

[原题链接](初级算法 - LeetBook - 力扣(LeetCode)全球极客挚爱的技术成长平台 (leetcode-cn.com))

  1. 同值冒泡法
    若当前值有冗余,则将紧接其后的同值冒泡到数组最后,同时数组长度减一。此法虽然容易想到,但冒泡时间代价太大(O(n^2))。
class Solution {
     /**
     * 输入一个升序排列的数组,原地删除重复出现的元素,
     * 返回删除后数组的新长度
     * 注意:必须在原地修改输入的数组并在使用O(1)额外空间的条件下完成
     * 设想:使用冒泡法将重复的元素冒泡到数组新尾部,每处理一次newLen--,
     * @param nums
     * @return
     */

    public int removeDuplicates(int[] nums) {
        int newLen = nums.length;
        for (int i = 0,j = 1; i < newLen; i = j - 1) {
            //处理第一个数的冗余
            if(j >= newLen)     //跳出循环的条件
                break;
            //比较nums[j]和nums[i]相等则做冒泡处理
            if(nums[j] == nums[i]){
                //冒泡
                bubbling(nums, j, newLen);
                newLen--;
            }
            //当前数不同于上一个数时开始处理当前数的冗余
            else j++;
        }
        return newLen;
    }

    /**
     * 冒泡:从nums当前位置冒泡到“新数组”最后
     * @param nums
     * @param index
     * @param len
     */
    private void bubbling(int[] nums, int index, int len){
        //考虑边界
        if(index == len -1) return;
        int temp = 0;
        for (int i = index, j = i; i < len - 1; i++) {
            j = i + 1;
            //交换
            temp = nums[i];
            nums[i] = nums[j];
            nums[j] = temp;
        }
    }

}

  1. 异值搜索法
    排序后,与当前值(下标为i)不同的值只可能出现在之后,顺序遍历并搜索第一个异值(下标为j),若找到则将其赋值给下一个位置,然后当前下标i++,继续搜索异值;否则j++,i不变。直到j遍历完数组。此法只需遍历一遍数组,时间复杂度为O(n)。

    class Solution {
        public int removeDuplicates(int[] nums) {
            int i = 0;
    
            for (int j = 1; j < nums.length; j++) {
                if (nums[i] != nums[j]) {
                    i++;
                    nums[i] = nums[j];
                }
            }
    
            return i + 1;
        }
    }
    

posted @ 2021-06-07 15:25  getHeading  阅读(68)  评论(0)    收藏  举报