1. 程式人生 > >【一次過】Lintcode 521. 去除重複元素

【一次過】Lintcode 521. 去除重複元素

給一個整數陣列,去除重複的元素。

你應該做這些事

1.在原陣列上操作
2.將去除重複之後的元素放在陣列的開頭
3.返回去除重複元素之後的元素個數

樣例

給出 nums = [1,3,1,4,4,2],你需要做以下操作

1.將重複元素扔在最後面 => nums = [1,3,4,2,?,?].
2.返回個數 4
實際上我們並不在意?是什麼

挑戰

1.O(n)時間複雜度.
2.O(nlogn)時間複雜度但沒有額外空間

注意事項

不需要保持原陣列的順序


解題思路1:

常見的思路是使用Map儲存。時間複雜度O(n),空間複雜度O(n)

public class Solution {
    /**
     * @param nums: an array of integers
     * @return: the number of unique integers
     */
    public int deduplication(int[] nums) {
        // write your code here
        Map<Integer,Integer> map = new HashMap<>();
        int i=0;
        int j=nums.length-1;
        
        for(; i<=j; ){
            if(map.get(nums[i]) == null)
                map.put(nums[i], 1);
            else
                map.put(nums[i], map.get(nums[i])+1);
                
            if(map.get(nums[i]) > 1){
                swap(nums, i, j--);
            }else{
                i++;
            }
        }
        
        return map.size();
    }
    
    private void swap(int[] nums, int i, int j){
        int temp = i;
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

解題思路2:

使用同向快慢指標。排序後用雙指標。一個快指標一直往前走,慢指標先不動。當快指標發現它指向的數和慢指標不一樣,就把該數丟給慢指標的後一個位置。慢指標++。最後返回慢指標的值+1。這個思路很不錯。

時間複雜度O(nlogn),空間複雜度O(1)

    public static int deduplication(int[] nums){
        Arrays.sort(nums);

        int i=0, j=1;
        while(j < nums.length){
            if(nums[j] != nums[i]){
                swap(nums, ++i, j);
            }
            j++;
        }

        return i+1;
    }

    private static void swap(int[] nums, int i, int j){
        int temp = nums[j];
        nums[j] = nums[i];
        nums[i] = temp;
    }