程序员算法&&数据结构&&leetcode刷题等精选

Divide and Conquer

2018-05-19  本文已影响7人  messi_wpy

算法之 分治法 Divide and Conquer


分治法:

分治法的设计思想是:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。

使用条件
分治法所能解决的问题一般具有以下几个特征:

所以可以看出分治法与递归联系紧密,时常一起出现,但也有区别,对于分治法,一定要注意会有和这一步,但有时在递归的过程中自动出现和这一步,不用太区分。要理解分治的思想。

主要应用

  1. 分:找到一个基准数;把小于这个数的数都放到左边,把大于这个数的数都放到右边;
  2. 解:递归快排
  3. 组合:因为当"求解"步骤中的两个递归调用结束时,其左、右两个子区间已有序。对快速排序而言,"组合"步骤无须做什么,可看作是空操作

leetcode题目分析:

  1. 53maximum-subarray:
    1.1 分解:这个数组只能出现在三个位置:从中间分,要么完全在左边,要么完全在右边,要么穿过中间,所以分三部分求最大
    1.2 求解:如果在左边或右边继续分,最后只剩一个数返回,对于穿过中间的,分成两部分求最大,每次都如此。
    1.3 组合:每次返回左边,右边,中间这三个中最大的
class Solution {
    public int maxSubArray(int[] nums) {
        return findMax(nums,0,nums.length-1);
    }
    public static int findMax(int []num,int left,int right){
        if (left>=right)return num[left];
        int mid=(left+right)/2;
        //寻找左边最大
        int lmax=findMax(num,left,mid-1);
        //寻找右边最大
        int rmax=findMax(num,mid+1,right);
        //寻找中间最大,并分成两部分,找从中间左边连续最大,中间到右边连续最大,最后加起来
        int mmax=num[mid],t=mmax;
        for (int i=mid-1;i>=left;i--){
            t+=num[i];
            mmax=Math.max(mmax,t);
        }
        t=mmax;
        for (int i=mid+1; i<=right; i++){
            t+=num[i];
            mmax=Math.max(mmax,t);
        }
        //合并
        return Math.max(mmax,Math.max(lmax,rmax));
    }
}
  1. 241. Different Ways to Add Parentheses:
    2.1 分:每次遇到符号,分成前后两部分,并记录该符号
    2.2 解:让左边的运算的所有结果去分别加后边运算的所有结果,分解直到只有两个数子,让他们运算,
    2.3 组合:每次的结果都计入数组返回。
class Solution {
    public List<Integer> diffWaysToCompute(String input) {
        List<Integer> res = new ArrayList<Integer>();  
        for (int i=0; i<input.length(); i++) {  
            char ch = input.charAt(i);  
            if (ch == '+' || ch == '-' || ch == '*') {  
                List<Integer> left = diffWaysToCompute(input.substring(0,i));  
                List<Integer> right = diffWaysToCompute(input.substring(i+1,input.length()));  
                for (int l : left) {  
                    for (int r : right) {  
                        switch(ch) {  
                        case '+' :  
                            res.add(l+r);  
                            break;  
                        case '-' :  
                            res.add(l-r);  
                            break;  
                        case '*' :  
                            res.add(l*r);  
                            break;  
                        }  
                    }  
                }  
            }  
        }  
        if (res.size() == 0) res.add(Integer.valueOf(input));  
        return res;  
    
    }
}
  1. 215. Kth Largest Element in an Array:
    这道题就只要先快速排序一下就可以找到了
上一篇 下一篇

猜你喜欢

热点阅读