分治策略:
1、将原始问题划分或归结为规模较小的子问题。
2、递归或者迭代求解每个子问题
3、将子问题的解综合得到原问题的解
注意:
1、子问题与原问题的性质完全一样
2、子问题之间可以彼此独立求解
3、递归停止时,子问题可以直接求解。
分治法的应用
1、二分检索
int binarySearch(vector<int> a,int begin,int end,int x){
int result;
int mid = (end-begin)/2;
while(begin<=end){
if(a[mid]==x){
return mid;
}else if(a[mid]>x){
end = mid-1;
mid = (end-begin)/2 + begin;
}else{
begin = mid+1;
mid = (end-begin)/2 + begin;
}
}
cout<<"没有找到"<<endl;
return -1;
}
时间复杂度分析:
可以解出:
2、二分归并排序
//合并
vector<int> merge(vector<int>a,vector<int>b){
int x=0,y=0;
vector<int> result;
while(x!=a.size()&&y!=b.size()){
if(a[x]<=b[y]){
result.push_back(a[x]);
x++;
}else{
result.push_back(b[y]);
y++;
}
}
if(x<a.size()){
for(int i=x;i<a.size();i++){
result.push_back(a[x]);
}
}
if(y<a.size()){
for(int i=y;i<b.size();i++){
result.push_back(b[y]);
}
}
return result;
}
//归并排序
vector<int> mergeSort(vector<int> a,int begin,int end){
if(begin = end){
return a;
}
if(begin<end){
int mid = (end-begin)/2;
vector<int> sa,sb;
std::copy(a.begin(), a.begin()+mid, std::back_inserter(sa));
std::copy(a.begin()+mid+1, a.end(), std::back_inserter(sb));
mergeSort(sa,0,sa.size()-1);
mergeSort(sb,0,sb.size()-1);
merge(sa,sb);
}
}
时间复杂度分析:
假设n为2的幂,二分归并排序最坏情况下时间复杂度:
3、Hanoi塔问题
void move(int number,stack<int> &a,stack<int>&b){
b.push(a.top());
a.pop();
}
stack<int> hanoi(int number,stack<int> &a,stack<int>&b,stack<int>&c){
if(number==1){
move(number,a,c);
}else{
hanoi(number-1,a,c,b);
move(number,a,c);
hanoi(number-1,b,a,c);
}
return c;
}
注:这个代码中将 A,B,C使用三个栈来表示,通过栈的变化过程,可以观察算法过程。初始输入,b,c为两个空栈。
时间复杂度分析:
欢迎关注我的微信公众号:菜鸡程序员的进阶