banner
ekko

ekko's blog

时间不在于你拥有多少,而在于你怎样使用
github
xbox
email

刪除排序陣列中的重複項

描述#

給定一個排序陣列,你需要在原地刪除重複出現的元素,使得每個元素只出現一次,返回移除後陣列的新長度。

不要使用額外的陣列空間,你必須在原地修改輸入陣列並在使用 O (1) 額外空間的條件下完成。

示例 1:

給定陣列 nums = [1,1,2], 

函數應該返回新的長度 2, 並且原陣列 nums 的前兩個元素被修改為 1, 2。 

你不需要考慮陣列中超出新長度後面的元素。

示例 2:

給定 nums = [0,0,1,1,1,2,2,3,3,4],

函數應該返回新的長度 5, 並且原陣列 nums 的前五個元素被修改為 0, 1, 2, 3, 4。

你不需要考慮陣列中超出新長度後面的元素。

說明:

為什麼返回數值是整數,但輸出的答案是陣列呢?

請注意,輸入陣列是以 **“引用”** 方式傳遞的,這意味著在函數裡修改輸入陣列對於調用者是可見的。

你可以想象內部操作如下:

// nums 是以“引用”方式傳遞的。也就是說,不對實參做任何拷貝
int len = removeDuplicates(nums);

// 在函數裡修改輸入陣列對於調用者是可見的。
// 根據你的函數返回的長度, 它會打印出陣列中該長度範圍內的所有元素。
for (int i = 0; i < len; i++) {
    print(nums[i]);
}

思路#

  • 從後往前遍歷該陣列,若當前元素與前一個相同,則從當前元素開始,陣列往前移一位
int removeDuplicates(int* nums, int numsSize){
    int now_size = numsSize;//記錄陣列大小
    for(int i=numsSize-1;i>0;i--) {
        if(nums[i-1] == nums[i]) {//出現重複元素
            now_size--;//陣列大小自減
            for(int j=0;j<numsSize-i-1;j++)//陣列前移
                nums[i+j] = nums[i+j+1];
        }    
    }
    return now_size;
    
}

進階#

  • 遍歷陣列,將重複過的元素置為最大或最小值,並記錄重複次數,陣列大小減重複次數即新陣列大小
  • 冒泡排序原陣列即可
void exchange(int* num1,int* num2) {
    int num = *num1;
    *num1 = *num2;
    *num2 = num;
}
int removeDuplicates(int* nums, int numsSize){
    int delete_nums = 0;
    for(int i=1;i<numsSize;i++) {
        if(nums[i] == nums[i-1]) {
            delete_nums++;
            nums[i-1] = 0x7fff;
        }
    }
    for(int i=0;i<numsSize;i++) {
        for(int j=numsSize-1;j>i;j--) {
            if(nums[j] < nums[j-1])
                exchange(nums+j,nums+j-1);
        }
    }
    return numsSize-delete_nums;
}

進階二#

  • 由於是有序陣列,因此最後的陣列每一位都是遞增且唯一的,所以第一位一定不需要動,從第二位開始,往後遍歷陣列,大於第一位則可與第二位交換,然後第三位繼續
void exchange(int* num1,int* num2) {
    int num = *num1;
    *num1 = *num2;
    *num2 = num;
}
int removeDuplicates(int* nums, int numsSize){
    if(numsSize < 2)
        return numsSize;
    for(int now = 1,last_find = 1;;now++) {//當前位置
        for(int find = last_find;;find++) {//尋找的指針
            if(find >= numsSize)//查找結束
                return now;
            if(nums[find] > nums[now-1]) {//找到指定元素
                if(find != now)
                    exchange(nums+now,nums+find);
                last_find = find + 1;//下次查找從下一個開始
                break;
            }
        }
    }
}
  • 這次的效率就比之前的高了很多很多,每一次的交換位置都是必要的
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。