蓝桥杯之分治算法
·
算法思想
规模为N的原问题的解无法直接求出,进行问题规模的缩减,划分子问题(这里子问题相互独立而且和原问题的解得性质是相同的,知识问题的规模缩小了)。如果子问题的规模仍然不够小,在进行子问题的划分,如此递归的进行下去,知道子问题规模足够小,很容易求出其解为止,最后将求出的小规模的问题的解合并为一个更大规模的问题的解,自底向上逐步求出原问题的解。
其实就是通过递归化繁为简,又简逐层回溯到原问题,常见的例子有快速排序和归并排序
快排分割找TopK问题
问题描述:
在一段序列中找第K大的元素,这里利用的是快速排序的思想,也可以用大小根堆解决此问题
算法思想:

代码描述:
int QuickSortFindTop(vector<int>& arr, int left, int right,int key)
{
int s_left = left;
int s_right = right;
int val = arr[left];
while (s_left < s_right)
{
while (s_left < s_right && arr[s_right] >= val)
s_right--;
if (s_left < s_right)
{
arr[s_left] = arr[s_right];
s_left++;
}
while (s_left < s_right && arr[s_left] <= val)
s_left++;
if (s_left < s_right)
{
arr[s_right] = arr[s_left];
s_right--;
}
}
arr[s_left] = val;
if (s_left < arr.size()-key)
{
QuickSortFindTop(arr, s_left + 1, right,key);
}
else if (s_left > arr.size() - key)
{
QuickSortFindTop(arr, left, s_left - 1,key);
}
else
{
return s_left;
}
}
归并排序
归并排序是最接近分治算法思想的,将序列递归到最小序列(只有一个元素),然后向上回溯,在回溯的过程中开辟空间进行排序.

代码实现:
void merge(vector<int>& vec, int left, int right, int mid)
{
vector<int>tmp;
tmp.reserve(right - left + 1);
int low = left;
int high = right;
int mmid = mid + 1;
//开始合并
while (low<=mid&&mmid<=right)
{
if (vec[low] <= vec[mmid])
{
tmp.push_back(vec[low]);
low++;
}
if (vec[low] > vec[mmid])
{
tmp.push_back(vec[mmid]);
mmid++;
}
}
//判断容器是否有剩余
while (low <= mid)
tmp.push_back(vec[low++]);
while (mmid <= right)
tmp.push_back(vec[mmid++]);
//此时,容器归并完成,开始放到原容器中
int nec = 0;
while (left <= right)
{
vec[left++] = tmp[nec++];
}
}
void MergeSort(vector<int>& vec, int left, int right)
{
if (left >= right)
return;
int mid = (left + right) / 2;
MergeSort(vec, left, mid);
MergeSort(vec,mid+1, right);
//分完了,开始回溯
merge(vec, left, right, mid);
}
更多推荐
所有评论(0)