分治法的基本思想
定义:将一个规模为n的问题分解为k个规模较小的子问题,这些子问题互相独立且与原问题相同。递归地解这些子问题,然后将各个子问题的解合并得到原问题的解。
算法设计模式
DIVIDE-AND-CONQUER(P)
{
if(|P| <= n0) //问题规模足够小,n0为规模阈值
then SOLVE(P); //解决小问题
subs = DIVIDE(P) //分解为子问题,subs为子问题集
for i = 1 to subs.length()
r[i]=DIVIDE-AND-CONQUER(subs[i]); //递归求解子问题
return COMBINE(r); //将各子问题的解合并为原问题的解
}
将规模为n的问题分成k个规模为n/m的子问题去解。设分解阈值n0=1,且CONQUER解规模为1的问题耗费1个单位时间。再设将原问题分解为k个子问题及用COMBINE将k个子问题的解合并为原问题的解需用f(n)个单位时间。则有:
分治法求解问题的空间复杂性:
运用分治策略的典型例子
二分搜索技术
题目描述:给定已排好序的n个元素a[0:n-1],现要在这n个元素中找出一特定元素x。
二分搜索算法基本思想:将n个元素分成个数大致相同的两半,取a[n/2]与x进行比较。如果相等,算法终止。如果x<a[a/2],则只在a的左半部搜索。如果x>a[n/2],则在右半部搜索。
具体算法描述(非递归)
package algorithm;
public class JavaTest3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] a = new int[] {1,3,5,7,9,13,16,18,33,56};
System.out.print(JavaTest3.binarySearch(a, 18, 10));
}
public static int binarySearch(int [] a, int x, int n){
//在a[0]<=a[1]<=...<=a[n-1]中搜索x
//找到x时返回其下标位置,否则返回-1
int left = 0;
int right = n-1;
while(left <= right){
int middle = (left + right)/2;
if(x == a[middle])
return middle;
if(x > a[middle])
left = middle + 1;
else
right = middle - 1;
}
return -1;
}
}
算法分析: