leetcode hot 100 - 75. 顏色分類
阿新 • • 發佈:2020-10-12
75. 顏色分類
題目描述
給定一個包含紅色、白色和藍色,一共n 個元素的陣列,原地對它們進行排序,使得相同顏色的元素相鄰,並按照紅色、白色、藍色順序排列。
此題中,我們使用整數 0、1 和 2 分別表示紅色、白色和藍色。
注意:
不能使用程式碼庫中的排序函式來解決這道題。
示例:
輸入: [2,0,2,1,1,0]
輸出: [0,0,1,1,2,2]
進階:
一個直觀的解決方案是使用計數排序的兩趟掃描演算法。 首先,迭代計算出0、1 和 2 元素的個數,然後按照0、1、2的排序,重寫當前陣列。 你能想出一個僅使用常數空間的一趟掃描演算法嗎?
思路一:不借助計數排序,但是需要兩次遍歷
思路和交換0很像,也是使用一個下標指向下個0應該存放的位置,另一個指標碰到0後把這個0放到正確的位置即可,但是這裡有3個數,分別是0, 1, 2, 所以應該遍歷兩遍,第一遍把所有0都放到最前面,第二遍把所有2放在最後面
1 class Solution { 2 public void sortColors(int[] nums) { 3 int len = nums.length; 4 int next = 0; 5 // 把所有的0移到最前面 6 for(int i = 0; i < len; i++){ 7 if(nums[i] == 0){ 8 int temp = nums[next]; 9 nums[next++] = nums[i];leetcode 執行用時:0 ms > 100.00%, 記憶體消耗:37.3 MB > 54.12%10 nums[i] = temp; 11 } 12 } 13 14 // 把所有的2移到最後面 15 next = len - 1; 16 for(int i = len - 1; i >= 0; i--){ 17 if(nums[i] == 2){ 18 int temp = nums[next]; 19 nums[next--] = nums[i]; 20 nums[i] = temp;21 } 22 } 23 } 24 }
複雜度分析:
時間複雜度:分別正序和倒序遍歷了一次陣列,所以時間複雜度為O(2n) 空間複雜度:O(1)思路二:雙指標 + 一次遍歷
其實就是思路一的一個改進版
分別使用一個指標 p0 指向下個0的應該放置的位置,使用一個p2 指向下個 2 應該放置的位置。另一個指標 i 從前往後掃描,碰到 0 就和 p0所指的元素進行交換,然後p0 指標後移,碰到 2 就和 p2 所指元素進行交換,p2--, 但是這時 i 不能前移,因為不能確定nums[i]和 nums[p2]進行交換後,如果是0的話需要和nums[p0]交換,所以需要下輪繼續判斷nums[i]
1 class Solution { 2 public void sortColors(int[] nums) { 3 int len = nums.length; 4 5 int p0 = 0, p2 = len - 1; 6 for(int i = 0; i <= p2; i++){ 7 if(nums[i] == 2){ 8 // 因為不能確定nums[p2]是什麼,如果是0的話需要和nums[p0]交換,所以需要下輪繼續判斷nums[i] 9 nums[i--] = nums[p2]; 10 nums[p2--] = 2; 11 }else if(nums[i] == 0){ 12 nums[i] = nums[p0]; 13 nums[p0++] = 0; 14 } 15 } 16 } 17 }
leetcode 執行用時:0 ms > 100.00%, 記憶體消耗:37.3 MB > 64.88%
複雜度分析:
時間複雜度:只遍歷了一遍陣列,所以時間複雜度為O(n)
空間複雜度:O(1)