刪除線性表中的重複元素

小記:煩躁ing,看不進去其它東西,就來刷刷leetcode的題目,今天刷到一道比較基礎的刪除已排序數組的題目,感覺很典型,就記錄了一下。

一、leetcode原題:刪除已排序數組重複元素

先給出leetcode原題:

Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length.

Do not allocate extra space for another array, you must do this in place with constant memory.

For example,
Given input array nums = [1,1,2],

Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively. It doesn't matter what you leave beyond the new length.

原題大意就是對於一個已經排好序的數組,刪除重複元素。要求空間複雜度爲O(1)。也就是不能重新申請新的數組。

解題思路:對於已經排好序的數組,那麼重複元素必然是聚集在一起的,也就是屬於前驅後繼的關係,所以可以通過比較相鄰的元素進行刪除。

1.空間換時間的方法(哈希思想)

如果不考慮空間的話,可以申請一個新的數組arrayFlag[n],這個數組的大小n必須要滿足大於或者等於給定數組的最大值。這個時候的哈希思想就是:以原數組的的值作爲下標,那麼這樣一個下標就只能對應一個元素,即使哈希一個重複的元素到同一下標,也只能存儲一次。

for(int i = 0;i <array.size();i++)
{
       arrayFlag[array[i]] = array[i];
}

for(int j = 0;j < arrayFlag.size(),j++)
{
        if(arrayFlag[j] != False)
              array[newSize++] = arrayFlag[j];
}

以上這種方法針對於無序數組也適用,但是缺點是新的生成的數組是不固定的,它是隨着原數組的最大元素決定的,所以不是很適合大數據。


2.逆向思維:保存不相同的元素(leetcode上的解決辦法)

刪除重複的元素,所以對於不相同的元素是需要存儲保留起來的,那麼我們可以設置一個變量就是存儲數組中不同元素的個數。具體的算法如下:

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int newSize = 1;
        if(nums.size() <= 1)
            return nums.size();
        for(int i = 1;i < nums.size();i++){
            if(nums[i] != nums[i-1]){
                nums[newSize] = nums[i];
                newSize++;
                }
            }
        return newSize;
    }
};

以上算法的優點在於時間和空間複雜度都是目前最低的情況了。用一個變量newSize來存儲不同的元素個數,如果前後兩個元素不同,那麼就保存不同的元素。需要注意的是如果只有一個元素或者爲空數組,那麼就返回數組原來的大小即可。還需要注意的是newSize的初始值是1,如果是0的話,那麼就會在只有兩個相同元素的數組總出現錯誤。

當然,這種思想也可以用在刪除某個給定的數組元素,保留不等於給定元素的的其它元素,然後就可以在O(n)的時間複雜度內實現刪除某個給定的元素了。(leetcode中的另外 一題)


二、拓展:刪除線性表中的重複元素

1.刪除無序數組中的重複元素

之前在一中提到的第一種方法也是可以針對無序數組的情況,第二種方法在針對無序數組之前,可以先調用其它一些排序算法對其進行排序。

2.刪除無序鏈表中的重複元素

線性表中除了數組,還有鏈表,針對鏈表的刪除重複元素,可以採用最能想到的算法:就是重新構造一個鏈表。先遍歷,從第一個元素開始依次將所有的元素都與其它元素進行比較,就可以得到一個新的沒有重複元素的鏈表,這種情況下的時間複雜度會是O(N^2).


以上就是刷到這題之後的一個想法,歡迎補充。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章