之前总结过排序的方法,在这里在写一下快速排序。
快速排序的本质就是分治算法,先找到该元素的正确位置,然后再将两边的元素递归进行快速排序。
代码如下:
int partition(vector<int>&nums,int left,int right)
{
int temp=nums[left];
while(left<right)
{
while(left<right&&nums[right]>=temp)
{
right--;
}
nums[left]=nums[right];
while(left<right&&nums[left]<=temp)
{
left++;
}
nums[right]=nums[left];
}
nums[left]=temp;
return left;
}
void quicksort(vector<int>&nums,int left,int right)
{
if(nums.size()==0||left>=right)
{
return ;
}
int pivot=partition(nums,left,right);
quicksort(nums,left,pivot-1);
quicksort(nums,pivot+1,right);
}
快速排序可以用来求解第K大数字:
class Solution {
public:
int partion(vector<int>&nums,int left,int right)
{
int pivot=nums[right];
while(left<right)
{
while(left<right&&nums[left]>=pivot)
{
left++;
}
nums[right]=nums[left];
while(left<right&&nums[right]<=pivot)
{
right--;
}
nums[left]=nums[right];
}
nums[left]=pivot;
return left;
}
int partion(vector<int>&nums,int left,int right)
{
int pivot=nums[left];
int l=left+1;
int r=right;
while(l<=r)
{
while(l<=r&&nums[l]>=pivot)
{
l++;
}
while(l<=r&&nums[r]<=pivot)
{
r--;
}
if(l<r)
{
swap(nums[l],nums[r]);
}
}
}
int findKthLargest(vector<int>& nums, int k)
{
int left=0;
int right=nums.size()-1;
while(true)
{
int pos=partition(nums,left,right);
if(pos==k-1)
{
return nums[pos];
}
if(pos<k-1)
{
left=pos+1;
}
else
{
right=pos-1;
}
}
}
};
leetcode中的Tag为sort的题目:
leetcode56:题目
区间合并,思路:将区间按照开始值进行排序,将第一个加入到结果中,然后依次遍历,如果遍历的元素的开始处大于等于结果最后一个元素的结束值,那么修改结果中最后一个元素中的结束值。否则,加入到结果中。
代码如下:
/**
* Definition for an interval.
* struct Interval {
* int start;
* int end;
* Interval() : start(0), end(0) {}
* Interval(int s, int e) : start(s), end(e) {}
* };
*/
static bool cmp(Interval a,Interval b)
{
return a.start<b.start||a.start==b.start&&a.end<b.end;
}
class Solution {
public:
vector<Interval> merge(vector<Interval>& intervals)
{
vector<Interval> ret;
int n=intervals.size();
if(n==0)
{
return ret;
}
sort(intervals.begin(),intervals.end(),cmp);
ret.push_back(intervals[0]);
for(int i=1;i<n;i++)
{
if(intervals[i].start<=ret.back().end)
{
ret.back().end=max(intervals[i].end,ret.back().end);
}
else
{
ret.push_back(intervals[i]);
}
}
return ret;
}
};
57:插入区间
解题思路:同上面的题目,给定一个区间,插入到数组中去。然后返回新的数组。从开始处进行遍历,如果当前的区间的结束值小于新区间的开始值,则加到结果中,如果当前遍历到的区间的开始值大于给定的新区间的开始值,那么跳出循环。否则,新区间和当前遍历的区间有交集,去两个区间的并集即可。
代码如下:
/**
* Definition for an interval.
* struct Interval {
* int start;
* int end;
* Interval() : start(0), end(0) {}
* Interval(int s, int e) : start(s), end(e) {}
* };
*/
class Solution {
public:
vector<Interval> insert(vector<Interval>& intervals, Interval newInterval)
{
vector<Interval> ret;
auto it=intervals.begin();
for(;it!=intervals.end();it++)
{
if((*it).start>newInterval.end)
{
break;
}
else
{
if((*it).end<newInterval.start)
{
ret.push_back(*it);
}
else
{
newInterval.start=min((*it).start,newInterval.start);
newInterval.end=max((*it).end,newInterval.end);
}
}
}
ret.push_back(newInterval);
for(;it!=intervals.end();it++)
{
ret.push_back(*it);
}
return ret;
}
};
题目描述:给定一个数组,求排好序后的相邻元素的最大间隔。
思路:先排序,然后找。
思路2:桶排序。
代码2:
class Solution {
public:
int maximumGap(vector<int> &num) {
if (num.size() < 2)
return 0;
//遍历一遍,找出最大最小值
int maxNum = num[0];
int minNum = num[0];
for (int i : num)
{
maxNum=max(maxNum,i);
minNum=min(minNum,i);
}
// 每个桶的长度len,向上取整所以加+
int len = (maxNum - minNum) / num.size() + 1;
//桶的个数:(maxNum - minNum) / len + 1,每个桶里面存储属于该桶的最大值和最小值即可,注意这里的最大最小值是局部的
vector<vector<int>> buckets((maxNum - minNum) / len + 1);
for (int x : num)
{
int i = (x - minNum) / len;
if (buckets[i].empty())
{
buckets[i].reserve(2);
buckets[i].push_back(x);
buckets[i].push_back(x);
} else
{
if (x < buckets[i][0])
buckets[i][0] = x;
if (x > buckets[i][1])
buckets[i][1] = x;
}
}
//gap的计算,For each non-empty buckets p, find the next non-empty buckets q, return min( q.min - p.max )
int gap = 0;
int prev = 0;
for (int i = 1; i < buckets.size(); i++)
{
if (buckets[i].empty())
continue;
gap = max(gap, buckets[i][0] - buckets[prev][1]);
prev = i;
}
return gap;
}
};