#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
void swap(int &a,int &b){
int t=a;a=b;b=t;
}
void print(int arr[],int l){
for(int i=0;i<=l;i++) cout<<arr[i]<<" ";
cout<<endl;
}
/*---------基本的快速排序---------*/
int partition(int arr[],int l,int r){
//arr[l+1...j]<v ; arr[j+1....i]>=v
int j=l;
for(int i=l+1;i<=r;i++)
if(arr[i]<arr[l]){
j++;swap(arr[i],arr[j]);
}
swap(arr[l],arr[j]);
return j;
}
void QuickSort(int arr[],int l,int r){
if(l>=r) return;
int p=partition(arr,l,r);
QuickSort(arr,l,p-1);
QuickSort(arr,p+1,r);
}
/*---------使用插入排序优化的快速排序---------*/
void insertsort(int arr[],int l,int r){
for(int i=r-1;i>=l;i--){
int t=arr[i];int j;
for(j=i;j+1<=r&&t>arr[j+1];j++)
arr[j]=arr[j+1];
arr[j]=t;
}
}
void QuickSort2(int arr[],int l,int r){
if(r-l<=15){
insertsort(arr,l,r);return;
}
//为快速排序添加随机索引
srand(time(NULL));
int t=rand()%(r-l)+l+1;
swap(arr[l],arr[t]);
int p=partition(arr,l,r);
QuickSort2(arr,l,p-1);
QuickSort2(arr,p+1,r);
}
/*---------双路快速排序---------*/
int partition_2ways(int arr[],int l,int r){
//为快速排序添加随机索引
srand(time(NULL));
int t=rand()%(r-l)+l+1;
swap(arr[l],arr[t]);
//arr[l+1...i-1]<=v ; arr[j+1....i]>=v
int i=l+1,j=r;
while(true){
while(i<=j&&arr[i]<=arr[l]) i++;
while(j>=i&&arr[j]>=arr[l]) j--;
if(i>=j) break;
swap(arr[i],arr[j]);i++;j--;
}
swap(arr[l],arr[j]);
return j;
}
void QuickSort_2ways(int arr[],int l,int r){
if(l>=r) return;
int p=partition_2ways(arr,l,r);
QuickSort_2ways(arr,l,p-1);
QuickSort_2ways(arr,p+1,r);
}
/*---------三路快速排序---------*/
void QuickSort_3ways(int arr[],int l,int r){
if(l>=r) return;
//为快速排序添加随机索引
srand(time(NULL));
int t=rand()%(r-l)+l+1;
swap(arr[l],arr[t]);
//arr[l+1,lt]<v ; arr[lt+1,i-1]==v ; arr[gt,r]>v
int lt=l,i=l+1,gt=r+1;
while(i<gt){
if(arr[i]<arr[l]){lt++;swap(arr[i],arr[lt]);i++;}
else if(arr[i]>arr[l]){gt--;swap(arr[i],arr[gt]);}
else {i++;}//arr[i]==arr[l]
}
swap(arr[l],arr[lt]);
//arr[l,lt-1]<v ; arr[lt,gt-1]==v ; arr[gt,r]>v
QuickSort_3ways(arr,l,lt-1);
QuickSort_3ways(arr,gt,r);
}
int main(int argc, char *argv[])
{
int arr[]={4,6,2,3,1,5,7,8};
QuickSort_3ways(arr,0,7);
print(arr,7);
return 0;
}
75. 颜色分类
给定一个包含红色、白色和蓝色,一共 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]
提示:
n == nums.length
1 <= n <= 300
nums[i] 为 0、1 或 2
进阶:
你可以不使用代码库中的排序函数来解决这道题吗?
你能想出一个仅使用常数空间的一趟扫描算法吗?
class Solution {
public:
void swap(int &a,int &b){
int t=a;a=b;b=t;
}
void sortColors(vector<int>& nums) {
int zero=-1,i=0,two=nums.size();
while(i<two){
if(nums[i]==0){zero++;swap(nums[i],nums[zero]);i++;}
else if(nums[i]==2){two--;swap(nums[i],nums[two]);}
else i++;
}
}
};
剑指 Offer 40. 最小的k个数
输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。
示例 1:
输入:arr = [3,2,1], k = 2
输出:[1,2] 或者 [2,1]
示例 2:
输入:arr = [0,1,2,1], k = 1
输出:[0]
限制:
0 <= k <= arr.length <= 10000
0 <= arr[i] <= 10000
class Solution {
public:
void swap(int &a,int &b){int t=a;a=b;b=t;}
int partition(vector<int>& arr,int l,int r){
srand(time(NULL));
int p=l+rand()%(r-l+1);
swap(arr[l],arr[p]);
int i=l+1,j=r;
while(true){
while(i<=j&&arr[i]<arr[l])i++;
while(i<=j&&arr[l]<arr[j])j--;
if(i>=j) break;
swap(arr[i],arr[j]);i++;j--;
}
swap(arr[l],arr[j]);
return j;
}
int selectK(vector<int>& arr,int l,int r,int k){
int t=partition(arr,l,r);
if(t==k) return arr[t];
if(k<t) return selectK(arr,l,t-1,k);
return selectK(arr,t+1,r,k);
}
vector<int> getLeastNumbers(vector<int>& arr, int k) {
if(k==0) return vector<int>(0);
int t=selectK(arr,0,arr.size()-1,k-1);
return vector<int>(arr.begin(),arr.begin()+k);
}
};
215. 数组中的第K个最大元素
在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
示例 1:
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4
说明:
你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。
class Solution {
public:
void swap(int &a,int &b){int t=a;a=b;b=t;}
int partition(vector<int>& arr,int l,int r){
srand(time(NULL));
int p=l+rand()%(r-l+1);
swap(arr[l],arr[p]);
int i=l+1,j=r;
while(true){
while(i<=j&&arr[i]<arr[l])i++;
while(i<=j&&arr[l]<arr[j])j--;
if(i>=j) break;
swap(arr[i],arr[j]);i++;j--;
}
swap(arr[l],arr[j]);
return j;
}
int selectK(vector<int>& nums,int l,int r,int k){
int t=partition(nums,l,r);
if(t==k) return nums[t];
if(k<t) return selectK(nums,0,t-1,k);
return selectK(nums,t+1,r,k);
}
int findKthLargest(vector<int>& nums, int k) {
return selectK(nums,0,nums.size()-1,nums.size()-k);
}
};