1. 程式人生 > >領釦網演算法學習筆記 -- 26

領釦網演算法學習筆記 -- 26

領釦網演算法學習筆記

本系列的演算法題目來自領釦網

陣列類演算法第三天

題目:刪除排序陣列中的重複項

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

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

示例:

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

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

解題過程:

思路:

看到這道題時,感覺很簡單,直接動手寫,寫完測試時發現怎麼做都不對,然後發現題目審錯了,開始我以為只是一個數組,沒有排序,需要在不使用額外空間的情況下以O(1)完成,所以我的思路是記錄最後一個不相同的元素的位置,初值為最後一個元素的位置,將相同的元素與最後一個元素交換,然後記錄的位置往前移一位,這樣就無需遍歷了。但是後面測試程式碼出現問題,後面審題才發現是有序的。於是思路簡化,直接定義一個變數用來記錄不同值的位置,然後將不同值依次從第一位賦值過去即可。

程式碼如下:

class Solution {
    public int removeDuplicates
(int[] nums) { // 因為陣列有序,所以重複值只能在一起,所以定義一個變數,迴圈遍歷陣列,當出現一個不同值時,數值加一 int numdate = 1; for(int i=0;i<nums.length-1;i++){ if(nums[i]!=nums[i+1]){ nums[numdate] = nums[i+1]; numdate++; } } return (numdate); }
} // 用時14ms

後續思考:

審題這事不容忽視,工作中,弄清業務需求也一樣,不然開發再完美,但是不符合需求,而且還浪費了時間。

領釦上面該題其他高質量範例:

class Solution {
    public int removeDuplicates(int[] nums) {
        int index = Integer.MAX_VALUE ;
        int counter = 0 ;
        for(int i=0; i<nums.length; i++){
            if(nums[i] == index) nums[i] = Integer.MAX_VALUE ;
            else {
                counter++ ;
                index = nums[i] ;
            }
        }
        Arrays.sort(nums);
        return counter ;
    }
}
// 用時10ms

自我整理:

​ 領釦上還有時間更短的示例,但是思路和我的類似,有的差不多隻是變數名不同,但是執行時間就是比我的快,百思不得其解。

​ 這個例子算是與我的區別比較大的一種。

​ 我的是比較相鄰的兩個值是否相同,這裡是當值沒有變化時,位置不變,繼續往後讀取比較,變化後再重新賦值比較;

​ 但是這個沒有對陣列進行排序,後面再使用Arrays.sort進行排序的。

程式碼優化:

class Solution {
    public int removeDuplicates(int[] nums) {
        int numdate = 0;
        for(int i=1;i<nums.length;i++){
            if(nums[numdate]!=nums[i]){
                numdate++;
                nums[numdate] = nums[i];
            }
        }
        return (numdate+1);
    }
}
// 用時8ms

自我整理:

優化內容就不總結了,主要明白了一點,原來去陣列中取指定位置的值也是需要時間的,所以這也是一個優化點。