【Leetcode】三路快排应用于75、88、215号问题
Author: Xin Pan
Date:2022.6.6
最近在从慕课网看liuyubobo老师的课,自己重新梳理整理下。这次分享如何使用三路快排解决一系列特殊条件的问题。包括75、88、215号问题。
【75】 颜色分类
输入:数据是没有排序的0、1、2三个数字组成的数组;
输出:经过排序的数组
解析
因为输入的数据只由三种数组成,那么这特定的条件要好好利用。这里用两个索引nzero
指向最后一个0,ntwo
指向第一个2所在的位置。那么nzero
和ntwo
之间就是1了。排序就算完成了。
我的答案
class Solution
{
public:
void sortColors(vector<int>& nums)
{
int nzero=-1,ntwo=nums.size();
for(int i=0;i<ntwo;)
{
if(nums[i]==0)
{
swap(nums[++nzero],nums[i++]);
}
else if (nums[i]==1)
{
i++;
}
else
{
assert(nums[i]==2);
swap(nums[--ntwo],nums[i]);
}
}
}
};
【88】合并两个有序数组
输入:给你两个按 非递减顺序 排列的整数数组 nums1
和 nums2
,另有两个整数 m
和 n
,分别表示 nums1
和 nums2
中的元素数目。
输出:请你 合并 nums2
到 nums1
中,使合并后的数组同样按 非递减顺序 排列。
解析
说来惭愧,现在还没想出怎么用三路快排来解,但是用逆双指针方法做出来了。
- TODO
容我再想想怎么做,后边补上三路快排的解法。
我的答案
class Solution
{
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n)
{
int np1=m-1,np2=n-1,ntail=m+n-1;
while(np1>=0 || np2>=0)
{
if(np1==-1)
{
nums1[ntail--]=nums2[np2--];
}
else if (np2==-1)
{
nums1[ntail--]=nums1[np1--];
}
else if (nums1[np1]<=nums2[np2])
{
nums1[ntail--]=nums2[np2--];
}
else
{
nums1[ntail--]=nums1[np1--];
}
}
}
};
【215】数组中的第K个最大元素
说起来这个题还是很有意思的,值得多做几次。
输入:给定整数数组 nums
和整数 k
。
输出:返回数组中第 k
个最大的元素。
解析
用快排思路做出来了。
- TODO
容我再想想怎么做,后边补上三路快排的解法。
我的答案
class Solution
{
public:
int findKthLargest(vector<int>& nums, int k)
{
int nl=0,nr=nums.size()-1;
while(true)
{
int nidx=__partition(nums,nl,nr);
if(nidx==k-1)
{
return nums[nidx];
}
else if (nidx<k-1)
{
nl=nidx+1;
}
else
{
nr=nidx-1;
}
}
}
private:
int __partition(vector<int> &nums,int nl,int nr)
{
int nvot=nums[nl];
while(nl<nr)
{
while(nl<nr && nums[nr]<=nvot)
{
nr--;
}
nums[nl]=nums[nr];
while(nl<nr && nums[nl]>=nvot)
{
nl++;
}
nums[nr]=nums[nl];
}
nums[nl]=nvot;
return nl;
}
};