leetcode 75
给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
对这道题进一步的进行推广,在数组中任意选择一个数pivot,将比pivot小的数在左边,比pivot大的数在右边,等于pivot载中间,举例:[3,4,4,2,7,9] 将pivot = 4,排序之后的结果就是[3,2,4,4,7,9]
第一种方式解决方式
代码的思路:(注意是开区间,还是闭区间)
初始情况:front = -1, rear = n, 分别是小于pivot,和大于pivot的区间分界点的指针,cur = 0 待处理的元素指针
数组空间划分成四部分 [0,front] 小于pivot , [rear,n-1]区间大于pivot,在(cur,rear)这个区间待处理的数据,(front,cur)等于pivot区间;
操作:
情况一:nums[cur] == pivot,直接cur++;
情况二:nums[cur] < pivot, 交换数组front+1和cur的位置,front++,cur++
情况三:nums[cur] > pivot 交换数组rear-1和cur的位置,rear–(注意cur此时是不变了的,这是因为 交换过来的元素还没有判断过)
判断的结束条件:cur和rear指针相遇
private void sortArrayByKey (int[] nums,int key) {
int front = -1,rear = nums.length;
int cur = 0;
while(cur < rear){
if(nums[cur] < key) {
swap(nums,++front,cur++);
} else if(nums[cur] > key) {
swap(nums,--rear,cur);
} else {
cur++;
}
}
}
第二种方式 其实实现逻辑也是通过指针划分区间的方式实现(弄清指针的含义,问题就解决一半了)
- 指针p1小于最右pivot的位置
- 指针p2指向小于等于最右pivot的位置
- 指针指向cur的大于pivot最右侧的一个指针
初始化 p1 = -1,p2 = -1,cur = 0,其实区间都是没有元素的
情况一:nums[cur] > pivot时,cur++;
情况二 :nums[cur] <= pivot, 将p2 + 1的位置和cur交换位置,p2++;
接着判断 nums[p2] < pivot成立,继续交换p1 + 1 和p2的位置,然后更新p1++;
private void sortArrayByPivotV2(int[] nums,int pivot) {
int p1 = -1,p2 = -1;
int cur = 0;
while(cur < nums.length) {
if(nums[cur] <= pivot){
swap(nums,++p2,cur);
if(nums[p2] < pivot) {
swap(nums,++p1,p2);
}
}
//当前元素大于pivot的时候如何处理呢? 什么也不做,只是更新cur下表
cur++;
}
}
欢迎小伙伴 评论区交流!!!