荷兰国旗问题与快速排序
目錄
- 荷蘭國旗問題
- 題目
- 思路
- 代碼
- 快速排序
- 思想
- 代碼實現
荷蘭國旗問題
題目
給定一個包含紅色、白色和藍色,一共 n 個元素的數組,原地對它們進行排序,使得相同顏色的元素相鄰,并按照紅色、白色、藍色順序排列。
此題中,我們使用整數 0、1 和 2 分別表示紅色、白色和藍色。
示例 1: 輸入:nums = [2,0,2,1,1,0] 輸出:[0,0,1,1,2,2]示例 2: 輸入:nums = [2,0,1] 輸出:[0,1,2]示例 3: 輸入:nums = [0] 輸出:[0]示例 4: 輸入:nums = [1] 輸出:[1]思路
這是一個典型的雙指針問題,由題意可知,我們最后需要將數組分成三部分, [0···,1···, 2···]
由此,我們定義兩個int類型的整數 p1,p2 。p1指向數組的第一個元素,p2指向數組的最后一個元素,分別代表數組三部分的邊界,在代碼運行的過程中,邊界逐漸向中心移動,移動的過程中同時對數組進行元素交換(排序)。
定義一個數組指針index,指向數組的第一個元素,開始遍歷。
- 遍歷結束標志,index <= p2(到達右邊界時停止)
- 如果index指向的元素小于1(即為0),那么就需要將該元素移動到數組的左部分,這時候,將index指向的元素與p1指向的元素交換即可,然后p1++(左邊界向右擴),index++(p1原來指向的元素是小于等于1的)。
- 如果index指向的元素等于1,那么index++即可,邊界不用動。
- 如果index指向的元素大于1(即為2),那么就需要將該元素移動到數組的右部分,這時候,將index指向的元素與p2指向的元素交換即可,然后p2–(右邊界向左擴),index不動(p2原來指向的元素是大于等于1的,index++后會跳過p2原來指向的元素)。
代碼
void sortColors(vector<int>& nums) {int p1 = 0;int p2 = nums.size()-1;int index = p1;while(index <= p2){if(nums[index] < 1){swap(nums[p1++], nums[index++]);}else if(nums[index] == 1){index++;}else{swap(nums[p2--], nums[index]);}}}快速排序
思想
快速排序和荷蘭國旗問題很相似
它是把一個數字先排到相應的位置,然后把比這個數小的元素和大的元素分開,不斷遞歸
比如,我們有這樣一組數
我們先把最后一個數(18)先排好,得到
我們會發現,比18小的數都排到了左邊,比18大的數都拍到了右邊
然后我們就得到3組數,(8,0,11)(18)(46,23)
數字18的位置以及排好了,然后去排左邊和右邊的一組數,同理,左邊會得到3組數,右邊會得到3組數(有一組數是空的),就這么循環下去,所有的數都排好了
我們會發現,快排的關鍵是將一個數字排好并把比它大的數和比它小的數分開,我們就可以利用荷蘭國旗問題的思想,利用雙指針就可以把數排好
代碼實現
#include <algorithm> #include <iostream> #include <ctime> #include <cstdlib> #include <vector> #include <cstring> using namespace std;int arr[100005]; int n; vector<int> mar(int left, int right);void quickSort(int left, int right) {if (left >= right - 1)return;int mid = (rand()%(right - left)) + left;swap(arr[mid], arr[right - 1]);vector<int> nums = mar(left, right);quickSort(left, nums[0]);quickSort(nums[1], right); }vector<int> mar(int left, int right) {int num = arr[right - 1];int index = left;int p1 = left;int p2 = right;while (index < p2){if (arr[index] < num)swap(arr[index++], arr[p1++]);else if (arr[index] > num)swap(arr[index], arr[--p2]);else++index;}return { p1,p2 }; }int main() {srand((unsigned)time(NULL));memset(arr, 0x00, sizeof(arr));cin >> n;for (int i = 0; i < n; ++i){cin >> arr[i];}quickSort(0, n);for (int i = 0; i < n; ++i){cout << arr[i] << " ";}return 0; }本文題目來自LeetCode
https://leetcode-cn.com/problems/sort-colors/
總結
以上是生活随笔為你收集整理的荷兰国旗问题与快速排序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: navicat输入法问题
- 下一篇: 数据结构试卷(节选)