這道題開始沒思路,但是後來用雙指針的分區域法一思考,基本很快就搞出來了。不過一是有個細節搞錯了,二是還有很多地方可以優化。
class Solution { public int removeDuplicates(int[] nums) { //空數組特判 if(nums.length==0) {return 0;} int p1=-1,p2=0;//p1指向重複區開頭,p2用於遍歷 int lastNum=0; while(p2<nums.length) { if(p2==0) { lastNum=nums[0]; p2++; } else { if(nums[p2]==lastNum) { //重複了 if(p1==-1) { //開闢重複區 p1=p2; p2++; } else { p2++; } } else if(nums[p2]!=lastNum) { //沒有重複,變換,修改lastnum lastNum=nums[p2]; if(p1==-1)// { p2++; } else { int num=nums[p1]; nums[p1]=nums[p2]; nums[p2]=num; p1++; p2++; } } } } //應該特判假如p1爲-1時 if(p1==-1) {return nums.length;} else {return p1;} } }
代碼開始寫成這樣,第一次錯誤是一直沒有重複項時p1爲初值-1。當然有幾個p2++可以提出來。
public int removeDuplicates(int[] nums) { if(nums == null || nums.length == 0) return 0; int p = 0; int q = 1; while(q < nums.length){ if(nums[p] != nums[q]){ nums[p + 1] = nums[q]; p++; } q++; } return p + 1; }
官方的這種解法當然簡潔很多,但感覺沒有之前那種套路百試不爽。
本人代碼簡化後:
class Solution { public int removeDuplicates(int[] nums) { //空數組特判 if(nums.length==0) {return 0;} int p1=nums.length,p2=1;//p1指向重複區開頭,p2用於遍歷。這裏p1初始值設成這個,就不用特判了
int lastNum=nums[0]; while(p2<nums.length) { if(nums[p2]==lastNum) { //重複了 if(p1==nums.length) { //開闢重複區 p1=p2; } } else if(nums[p2]!=lastNum) { //沒有重複,變換,修改lastnum lastNum=nums[p2]; if(p1!=nums.length)// { int num=nums[p1]; nums[p1]=nums[p2]; nums[p2]=num; p1++; } } p2++; } //應該特判假如p1爲-1時,這裏第一次搞錯了 return p1; } }