分治算法

来源:互联网 发布:贝叶斯网络分析软件 编辑:程序博客网 时间:2024/04/24 04:48

分治法所能解决的问题一般具有以下几个特征:
1) 该问题的规模缩小到一定的程度就可以容易地解决
2) 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质。
3) 利用该问题分解出的子问题的解可以合并为该问题的解;
4) 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子子问题。
第一条特征是绝大多数问题都可以满足的,因为问题的计算复杂性一般是随着问题规模的增加而增加;
第二条特征是应用分治法的前提它也是大多数问题可以满足的,此特征反映了递归思想的应用;、
第三条特征是关键,能否利用分治法完全取决于问题是否具有第三条特征,如果具备了第一条和第二条特征,而不具备第三条特征,则可以考虑用贪心法或动态规划法。
第四条特征涉及到分治法的效率,如果各子问题是不独立的则分治法要做许多不必要的工作,重复地解公共的子问题,此时虽然可用分治法,但一般用动态规划法较好。

分治法在每一层递归上都有三个步骤:

step1 分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题;step2 解决:若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题step3 合并:将各个子问题的解合并为原问题的解。

看了那么多生硬的文字,没啥感觉还是老一套,做题!
一、寻找假币

public class FalseCoin {    public static void main(String[] args) {        int arr[]={2,2,2,2,2,1,2,2};        int x=method(arr,0,arr.length-1);        if(x==-1){            System.out.println("没有假币");        }else{            System.out.println("第"+(x+1)+"个金币是假币!");        }    }    private static int method(int[] arr, int l, int r) {        int re,sum1=0,sum2=0,mid;        if(l==r){               //筛选到最后一个币时            if(arr[l]==2){                return -1;            }else{                return l;            }        }        //筛选到只有两个金币时        if(l+1==r){            if(arr[l]<arr[r]){                re=l;                return re;            }else if(arr[l]>arr[r]){                re=r;                return re;            }else{                return -1;            }        }        //金币数是偶数        if((r-l+1)%2==0){            for(int i=l;i<=l+(r-l)/2;i++){      //前半段 求和                sum1=sum1+arr[i];            }            for(int i=l+(r-l)/2+1;i<=r;i++){    //后半段 求和                sum2=sum2+arr[i];            }            if(sum1>sum2){                re=method(arr,l+(r-l)/2+1,r);                return re;            }else if(sum1<sum2){                re=method(arr,l,l+(r-l)/2);                return re;            }else{                return re=-1;//sum1=sum2没有假币,返回负数            }        }        //金币数是奇数时        else{            for(int i=l;i<=l+(r-l)/2-1;i++){        //前半段 求和                sum1=sum1+arr[i];            }            for(int i=l+(r-l)/2+1;i<=r;i++){        //后半段 求和                sum2=sum2+arr[i];            }            mid=l+(r-l)/2;            if(sum1>sum2){                re=method(arr,l+(r-l)/2+1,r);                return re;            }else if(sum1<sum2){                re=method(arr,l,l+(r-l)/2-1);                return re;            }else{                re=method(arr,mid,mid);                return re;            }        }    }}

二、二分查找

public class BinarySearch {    public static int search(int target, int[] data,int min, int max) {        if (min > max) {            return -1;        }        int n = (min + max) / 2;        if (target > data[n]) {            min = n + 1;        }        if (target < data[n]) {            max = n - 1;        }        if (target == data[n]) {            return n;        } else {            return search(target,data, min, max);        }    }    public static void main(String[] args) {        int[] arr = { 1, 2, 7, 9, 25, 44, 66, 99 };        System.out.println(search(50, arr,0, arr.length - 1));        System.out.println(search(66, arr,0, arr.length - 1));    }}

三、快速排序
http://blog.csdn.net/java_zero2one/article/details/51567506

四、合并排序
http://blog.csdn.net/java_zero2one/article/details/51658467

0 0
原创粉丝点击