LeetCode日记——【算法】分治专题

   预备知识:什么是分治

        分治,字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题,直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。在计算机科学中,分治法就是运用分治思想的一种很重要的算法。分治法是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)等等。

 

题1:给表达式加括号

难度:Medium

链接

题目描述:

给定一个含有数字和运算符的字符串,为表达式添加括号,改变其运算优先级以求出不同的结果。你需要给出所有可能的组合的结果。有效的运算符号包含 +, - 以及 * 。

示例 1:

输入: "2-1-1"
输出: [0, 2]
解释:
((2-1)-1) = 0
(2-(1-1)) = 2
示例 2:

输入: "2*3-4*5"
输出: [-34, -14, -10, -10, 10]
解释:
(2*(3-(4*5))) = -34
((2*3)-(4*5)) = -14
((2*(3-4))*5) = -10
(2*((3-4)*5)) = -10
(((2*3)-4)*5) = 10

代码:

 1 class Solution {
 2     public List<Integer> diffWaysToCompute(String input) {
 3         List<Integer> ways = new ArrayList<>();
 4         //对于字符串的每一个字符按顺序遍历
 5         for(int i=0;i<input.length();i++){
 6             //取出当前字符存为c
 7             char c=input.charAt(i);
 8             //若当前字符为运算符
 9             if(c=='+' || c=='-' || c=='*'){
10                 List<Integer> left = diffWaysToCompute(input.substring(0,i));
11                 List<Integer> right = diffWaysToCompute(input.substring(i+1));
12                 for(int l:left){
13                     for(int r:right){
14                         switch(c){
15                             case '+':
16                                 ways.add(l+r);
17                                 break;
18                             case '-':
19                                 ways.add(l-r);
20                                 break;
21                             case '*':
22                                 ways.add(l*r);
23                                 break;
24                         }
25                     }
26                 }
27             }
28         }
29         if(ways.size()==0){
30             ways.add(Integer.valueOf(input));
31         }
32         return ways;
33     }
34 }

 分析:

按顺序遍历每个字符,若遍历到运算符,就将表达式递归地分成两部分,当前字符的左边部分与当前字符的右边部分(均不包含当前字符)。然后做相应的运算。

 

  题1:不同的二叉搜索树

难度:Medium

链接

题目描述:

给定一个整数 n,生成所有由 1 ... n 为节点所组成的 二叉搜索树 。

示例:

输入:3
输出:
[
  [1,null,3,2],
  [3,2,null,1],
  [3,1,null,null,2],
  [2,1,3],
  [1,null,2,null,3]
]
解释:
以上的输出对应以下 5 种不同结构的二叉搜索树:

1                     3                    3                   2                   1
 \                     /                     /                   / \                    \
  3                 2                    1                  1   3                   2
  /                 /                        \                                             \
2                1                         2                                             3

代码:

 1 /**
 2  * Definition for a binary tree node.
 3  * public class TreeNode {
 4  *     int val;
 5  *     TreeNode left;
 6  *     TreeNode right;
 7  *     TreeNode() {}
 8  *     TreeNode(int val) { this.val = val; }
 9  *     TreeNode(int val, TreeNode left, TreeNode right) {
10  *         this.val = val;
11  *         this.left = left;
12  *         this.right = right;
13  *     }
14  * }
15  */
16 class Solution {
17     public List<TreeNode> generateTrees(int n) {
18         if (n < 1) {
19         return new LinkedList<TreeNode>();
20         }
21         return generateSubtrees(1, n);        
22     }
23 
24     private List<TreeNode> generateSubtrees(int s, int e) {
25         List<TreeNode> res = new LinkedList<TreeNode>();
26         if (s > e) {
27             res.add(null);
28             return res;
29         }
30         for(int i=s;i<=e;++i){
31             List<TreeNode> leftSubtrees = generateSubtrees(s, i - 1);
32             List<TreeNode> rightSubtrees = generateSubtrees(i + 1, e);
33             for (TreeNode left : leftSubtrees) {
34                 for (TreeNode right : rightSubtrees) {
35                     TreeNode root = new TreeNode(i);
36                     root.left = left;
37                     root.right = right;
38                     res.add(root);
39                 }
40             }
41         }
42         return res;
43     }
44 }

分析:

对1~n中每一个元素进行遍历。将元素组递归地分为左右两部分(不包括当前元素)。创建当前元素代表的当前根节点,然后分别将左边部分作为左子节点,右边部分作为右子节点。

 

分治专题完结撒花~

 

posted @ 2020-06-04 10:29  菅兮徽音  阅读(188)  评论(0编辑  收藏  举报