題目描述:html
給定一個包含紅色、白色和藍色,一共 n 個元素的數組,原地對它們進行排序,使得相同顏色的元素相鄰,並按照紅色、白色、藍色順序排列。java
此題中,咱們使用整數 0、 1 和 2 分別表示紅色、白色和藍色。算法
注意:
不能使用代碼庫中的排序函數來解決這道題。數組
示例: 輸入: [2,0,2,1,1,0] 輸出: [0,0,1,1,2,2]
進階:一個直觀的解決方案是使用計數排序的兩趟掃描算法。函數
首先,迭代計算出0、1 和 2 元素的個數,測試
而後按照0、一、2的排序,重寫當前數組。spa
你能想出一個僅使用常數空間的一趟掃描算法嗎?指針
代碼實現:map存儲鍵同樣的元素,可是提交不經過,本地測試經過,應該是leetcode的測試用例的問題code
class Solution { public static List<Integer> sortColors(int[] nums) { Map<Integer, List<Integer>> map = new HashMap<>(3); map.put(0, new ArrayList<>()); map.put(1, new ArrayList<>()); map.put(2, new ArrayList<>()); for (int i = 0; i < nums.length; i++) { map.get(nums[i]).add(nums[i]); } List<Integer> list0=map.get(0); List<Integer> list1=map.get(1); List<Integer> list2=map.get(2); List<Integer> result = new ArrayList<>(list0); result.addAll(list1); result.addAll(list2); return result; } }
雙指針:由於0
和2
分別在排序以後必定在最左邊,和最右邊,因此咱們用雙指針分別記錄最左邊,和最右邊,依次把0
,2
交換過去!,當元素爲1時不處理(相似於荷蘭國旗問題)htm
代碼實現:
class Solution { public void sortColors(int[] nums) { int left = 0; int n = nums.length; for (int i = 0;i < n;i ++) { if (nums[i] == 0) { int tmp = nums[i]; nums[i] = nums[left]; nums[left] = tmp; left++; } } int right = n - 1; for (int i = n - 1; i >= left; i--) { if (nums[i] == 2) { int tmp = nums[i]; nums[i] = nums[right]; nums[right] = tmp; right--; } } } }
時間複雜度 :因爲對長度 NN的數組進行了一次遍歷,時間複雜度爲O(N) 。
空間複雜度 :因爲只使用了常數空間,空間複雜度爲O(1) 。