領釦網演算法學習筆記 -- 26
阿新 • • 發佈:2018-11-24
領釦網演算法學習筆記
本系列的演算法題目來自領釦網
陣列類演算法第三天
題目:刪除排序陣列中的重複項
給定一個排序陣列,你需要在原地刪除重複出現的元素,使得每個元素只出現一次,返回移除後陣列的新長度。
不要使用額外的陣列空間,你必須在原地修改輸入陣列並在使用 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
自我整理:
優化內容就不總結了,主要明白了一點,原來去陣列中取指定位置的值也是需要時間的,所以這也是一個優化點。