題目描述:
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/array-partition-i
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。
最近按數據結構刷的題,不少簡單題都可以直接調用有些語言裏的內置函數解決,這道題挑出來寫純粹是複習一下快速排序的寫法,題目乍一看題意有點奇怪,仔細一分析就能發現要達到Min(ai,bi)總和最大,就必須讓最小的數跟次小的數凡在一個Pair裏,否則次小數會作爲另一個Pair裏的較小數出現,從而使得最後總和不能達到最大;
因此這題最直觀的思路就是把數組排序,將下標爲偶數的所有數求和輸出即可。
這裏貼一下自己寫的快速排序的代碼:
void myQuickSort(int left, int right, vector<int> &nums)
{
if(left>=right) return ; // 遞歸結束條件
int flag = nums[left];
int alert=1; //alert==1表示從右開始,alert==0表示從左開始
int templeft=left, tempright=right;
while(templeft<tempright) // 一趟遍歷下來,flag的最終位置確定
{
if(alert) //從右開始
{
if(nums[tempright]>=flag) //右邊的數大於基準數
{
tempright--; alert=1;continue; //右指針--,不交換數字
}
else //右邊的數小於基準數,
{
nums[templeft] = nums[tempright]; //與左指針數字交換
templeft++;alert=0;continue; //左指針++,並且下一趟從左邊開始
}
}
else
{
if(nums[templeft]<flag) //從左開始
{
templeft++; alert=0;continue;
}
else
{
nums[tempright]=nums[templeft];
tempright--;alert=1;continue;
}
}
}
if(tempright==templeft) nums[templeft] = flag; //循環結束是,左指針應該等於右指針,未基準數的最終位置
myQuickSort(left,templeft-1,nums); //遞歸遍歷基準數左邊
myQuickSort(templeft+1,right,nums); //遞歸遍歷基準數右邊
}
一開始寫快排的時候參數沒有left,right指針,發現怎麼寫都很彆扭,後來查了一下發現快排是不能原地排序的,因爲遞歸的時候會發現要以原數組的一部分初始化爲一個新數組,可能會出現意想不到的問題,後來加了left,right指針,一切就通順多啦;
還有一個有意思的地方,我用vector的內置函數sort提交後發現比我寫的快排速度要更快,內存消耗也少一些,以前一直以爲STL內置sort函數就是快速排序,查閱了一些資料後發現並不只是快排,還結合了歸併排序和插入排序,
當數據量過大的時候,sort函數會使用歸併排序的思想先將大數組分爲規模中等的數組,分別排序好後再進行歸併;
當遞歸深度過深時,我們知道當數組基本有序時快排的效率很低,因爲遞歸深度很深,而此時插入排序就接近最好的情況,於是sort函數會使用插入排序;
查看了一下STL sort()的源碼,有點頭暈,模板很多,準備有精力研究的時候再看看吧。