算法——递归&&分治

76 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,[点击查看活动详情]

算法:一个问题的解决流程和步骤。是针对不同的特定问题的解决策略和思想。

递归

是程序调用自身的编程技巧,函数调用关系。
要有:边界条件,递归前进段,递归返回段

分治

将原问题分成n个规模较小,并结构与原问题相似的子问题。迭代,递归的解决子问题后合并。
用数学归纳法解决的问题,都可以使用分治思想。
分治思想不一定使用递归结构。

操作

(1)分解:将原问题分解成一系列子问题
(2)解决:递归的求解各个子问题,若子问题足够小,直接求解
(3)合并:将子问题的结果合并成原问题。

条件

1,原问题与分解成的小问题具有相同的模式
2,原问题分解成的子问题可以独立求解,子问题之间没有相关性
3,具有分解终止条件,当问题足够小,可以直接求解
4,可以将子问题合并成原问题,而这个合并操作的复杂度不能太高。

问题

1,前n项求和.
2,n的阶乘。
3,斐波那契数列
4,大整数乘法问题——如果将大整数分成更多段则导致快速傅里叶变换的产生。

long product=multi(x,y,4);
public static long multi(long x,long y,int n){
    long A=(long)(x/Math.pow(10,n/2));
    long B=(long)(x-A*Math.pow(10,n/2));
    long C=(long)(y/Math.pow(10,n/2));
    long D=(long)(y-C*Math.pow(10,n/2));
    long E=multi(A,C,n/2);
    long F=multi(B,D,n/2);
    long G=multi(A+B,C+D,n/2);
    return (long)(E*Math.pow(10,n)+(G-E-F)*Math.pow(10,n/2)+F);
}

5,全排列

public class Main{
    private static TreeSet<String> set = new TreeSet<>();
    public static void main(String[] args){
        String s="ABC";
        char[] arr=s.toCharArray();
        permutation(arr,0,arr.length-1);
        for(String sub:set){
            System.out.println(sub);
        }
    }
    private static void perpermutation(char[] arr,int from,int to){
        if(from == to){
            set.add(String.valueOf(arr));
        }
        for(int i=from;i<=to;i++){
            swap(arr,i,from);
            permutation(arr,from+1,to);
        }
    }
    public static void swap(char[] arr,int a,int b){
        char temp = arr[a];
        arr[a]=arr[b];
        arr[b]=temp ;
    }
}

5,棋盘覆盖问题\ 6,汉诺塔问题

函数的运行是基于栈的