分冶法的思想及其应用系列

分冶法的思想及其应用系列

分冶法的思想

把复杂问题分成较小的与原问题类型相同的子问题,可以求解所有的子问题的解,可以将子问题的解合并成原复杂问题的解

1.原问题可以分解成若干个相同类型的子问题

2.(缩小到一定规模的)子问题可以容易解决

3.子问题的解可以合并成原问题的解

分冶法的应用

1.给表达式加括号(列出所有优先级下的表达式输出)

Leetcode

Input: “2-1-1”.

((2-1)-1) = 0

(2-(1-1)) = 2

Output : [0, 2]

(1).以运算符为划分,表达式字符串可以继续划分成类型相同的表达式字符串的子问题
(2).(当表达式字符串缩小成一定规模)子问题“1-1”可以求解
(3).以运算符划分可以成为两种情况的子问题,a. 以第一个减号运算符划分"2"和“1-1” ,b.以第二个减号运算符划分"2-1"和“1”,a和b的解合并的解正是问题添加括号(列出所有优先级情况)的所有解
public List<Integershi> diffWaysToCompute(String input) {
        List<Integer> ways = new ArrayList<>();
        for (int i = 0; i < input.length(); i++) {
            char c = input.charAt(i);
            if (c == '+' || c == '-' || c == '*') {
                List<Integer> left = diffWaysToCompute(input.substring(0, i));
                List<Integer> right = diffWaysToCompute(input.substring(i + 1));
                for (int l : left) {
                    for (int r : right) {
                        switch (c) {
                            case '+':
                                ways.add(l + r);
                                break;
                            case '-':
                                ways.add(l - r);
                                break;
                            case '*':
                                ways.add(l * r);
                                break;
                        }
                    }
                }
            }
        }
        if (ways.size() == 0) {
            ways.add(Integer.valueOf(input));
        }
        return ways;
    }

在这里插入图片描述
在这里插入图片描述

2.给定一个数字 n,要求生成根节点分别为 1…n 的所有二叉搜索树。

Leetcode 在这里插入图片描述

(1).以小于等于n的任意数为划分,剩下的数可以继续划分成类型相同的子问题
(2).(当数组缩小成一定规模)子问题“1”可以求解
(3).以数划分可以成为三种情况的子问题,a. 以1划分为3和2 ,b.以2划分为1和3,c,以3划分为1和2. 以二叉树的特性(当前结点:左边的结点小于我,右边的结点大于我),所以b只有一种左1右3,a和c有两种情况的子问题,以a为例当先右3时2就在3下面的左边,先2时3就在2下面的右边,同理可以判断c. a,b,c的所有解合并的解正是问题给定数字 3,生成根节点分别为 1,2,3的所有二叉搜索树
public class TreeNode {
          int val;
          TreeNode left;
          TreeNode right;
          TreeNode() {}
          TreeNode(int val) { this.val = val; }
          TreeNode(int val, TreeNode left, TreeNode right) {
            this.val = val;
             this.left = left;
            this.right = right;
         }
    }
    public List<TreeNode> generateTrees(int n) {
        if (n < 1) {
            return new LinkedList<TreeNode>();
        }
        return generateSubtrees(1, n);
    }

    private List<TreeNode> generateSubtrees(int s, int e) {
        List<TreeNode> res = new LinkedList<TreeNode>();
        if (s > e) {
            res.add(null);
            return res;
        }
        for (int i = s; i <= e; ++i) {
            List<TreeNode> leftSubtrees = generateSubtrees(s, i - 1);
            List<TreeNode> rightSubtrees = generateSubtrees(i + 1, e);
            for (TreeNode left : leftSubtrees) {
                for (TreeNode right : rightSubtrees) {
                    TreeNode root = new TreeNode(i);
                    root.left = left;
                    root.right = right;
                    res.add(root);
                }
            }
        }
        return res;
    }

3.快速排序。

(1).以起始数为基准划分成左右两个子问题,子问题还可以继续划分成类型相同的子问题
(2).(当数组缩小成一定规模)子问题1可以求解,排序为1
(3).合并所有子问题可以合成有序数组
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值