What
分治法是将一个难以直接解决的大问题,分割成一些规模较小的相同问题,小问题解决,大问题随之解决。
分治法在每一层递归上都有三个步骤:
step1 分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题;
step2 解决:若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题
step3 合并:将各个子问题的解合并为原问题的解。
经典例题
全排列问题
问题描述:1 2 3 4 问有几种排列方式
分析:
分解:4个数的排列方式数 = 1开头的排列方式数 + 2开头的排列方式数 + 3开头的排列方式数 + 4 开头的排列方式数
解决: 1开头的排列方式数 = 1 开头 + 剩余3个数的排列方式数(两两互相交换),依次类推,当只剩1个数时输出本次排列方式
合并: 每个数开头的排列方式共同组成4个数的总排列方式
代码实现
public class HelloWorld {
public static void main(String []args) {
Permutation(new char[]{'1','2','3'},0);
}
public static void Permutation(char chs[],int start )
{
if(start==chs.length-1)
{
System.out.println(chs);
return;
//如果已经到了数组的最后一个元素,前面的元素已经排好,输出。Arrays.toString(chs);
}
for(int i=start;i<=chs.length-1;i++)
{
//把第一个元素分别与后面的元素进行交换,递归的调用其子数组进行排序
Swap(chs,i,start);
Permutation(chs,start+1);
Swap(chs,i,start);
//子数组排序返回后要将第一个元素交换回来。
//如果不交换回来会出错,比如说第一次1、2交换,第一个位置为2,子数组排序返回后如果不将1、2
//交换回来第二次交换的时候就会将2、3交换,因此必须将1、2交换使1还是在第一个位置
}
}
public static void Swap(char chs[],int i,int j)
{
char temp;
temp=chs[i];
chs[i]=chs[j];
chs[j]=temp;
}
}
前几遍可能都看不懂,可以在纸上画下程序执行时 i ,start 的值。