LeetCode有代表性的題解---分治思想(五)

1.給表達式加括弧(設計優先級)

241. 爲運算表達式設計優先級

給定一個含有數字和運算符的字符串,爲表達式添加括號,改變其運算優先級以求出不同的結果。你需要給出所有可能的組合的結果。有效的運算符號包含 +, - 以及 * 。

示例 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

解題思想:遇到運算符將表達式分爲兩部分,即運算符(+ - *)左邊部分和右邊部分,每部分的計算結果存儲於List中,根據運算符(+-*)循環計算當前表達式最終結果。 對於存儲於List中左右兩部分的計算結果遞歸進行運算。

以 2 * 3 - 4 * 5 爲例。

2 和 3 - 4 * 5 兩部分,中間是 * 號相連。

2 * 3 和 4 * 5 兩部分,中間是 - 號相連。

2 * 3 - 4 和 5 兩部分,中間是 * 號相連。

有了兩部分的結果,然後再通過中間的符號兩兩計算加入到最終的結果中即可。

比如第一種情況,2 和 3 - 4 * 5 兩部分,中間是 * 號相連。

2 的解就是 [2],3 - 4 * 5 的解就是 [-5, -17]。

把兩部分解通過 * 號計算,最終結果就是 [-10, -34]。

另外兩種情況也類似。

然後還需要遞歸出口。

如果給定的字符串只有數字,沒有運算符,那結果就是給定的字符串轉爲數字。

比如上邊的第一種情況,2 的解就是 [2]。

JAVA代碼如下:

class Solution {
    //解決思路:遞歸解法
    //  遇到運算符將表達式分爲兩部分,即運算符(+ - *)左邊部分和右邊部分,對於每部分的結果再遞歸進行運算,每部分的計算結果存儲與List中
    public List<Integer> diffWaysToCompute(String input) {
        List<Integer> ways = new ArrayList<>();
        int len=input.length();
        for(int i=0;i<len;i++){
            char ch=input.charAt(i);
            //如果當前字符是運算符,則將表達式分爲兩部分分別計算表達式左邊的結果和右邊的結果
            if(ch=='+'||ch=='-'||ch=='*'){
                List<Integer> left=diffWaysToCompute(input.substring(0,i));//subString()函數[0,i)左閉右開
                List<Integer> right=diffWaysToCompute(input.substring(i+1));//從i+1到最後
                for(int l:left){
                    for(int r:right){
                        if(ch=='+'){
                            ways.add(l+r);
                        }else if(ch=='-'){
                            ways.add(l-r);
                        }else{
                            ways.add(l*r);
                        }
                    }
                }
            }
        }
        //當傳入的input表達式中沒有運算符,
        if(ways.size()==0)
            ways.add(Integer.valueOf(input));
        return ways;
    }
}

2.構建不同的二叉搜索樹

95. 不同的二叉搜索樹 II

給定一個整數 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
 

提示:

0 <= n <= 8

解題思想:根據二叉搜索樹的性質,根的左樹所有的節點的value值小於根的value值,根的右子樹所有節點的value值大於根的value值。根據傳入的參數n,依次遍歷n作爲root,小於n的部分作爲左子樹節點遞歸構建左子樹,大於n的部分做爲右子樹節點遞歸構建右子樹,構建的左右子樹均保存在List<TreeNode>中,最後根據構建的不同左右子樹進行拼接。

JAVA代碼:

import java.util.ArrayList;
import java.util.List;

/**
 * Created by 高先森 on 2020/7/1.
 */
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 class leetcode_95_biSearchTree {
    public static void main(String[] args){
        System.out.println(generateTrees(3));
    }
    public static List<TreeNode> generateTrees(int n) {
        if(n<=0)
            return new ArrayList<TreeNode>();
        else
            return createTree(1,n);
    }
    public static List<TreeNode> createTree(int begin,int end) {
        List<TreeNode> resList=new ArrayList();
        //1.遞歸出口正確的處理
        if(begin>end) {
            resList.add(null);
            return resList;
        }
        //  錯誤處理
//        if(begin>end)
//            return new ArrayList<>();//返回一個空的ArrayList,無法提取空子樹(null)
        //2.構建二叉搜索樹
        for(int i=begin;i<=end;i++){
            //2.1.建立根節點
            TreeNode root;//此處如果直接是TreeNode root=new TreeNode(i);則每次修改左右子樹都是在同一個根上做變動,添加後面的樹,之前保存的樹也會變動
            //2.2.遞歸構建左右子樹
            for(TreeNode treeNode_left:createTree(begin,i-1)){
                for(TreeNode treeNode_right:createTree(i+1,end)){
                    root=new TreeNode(i);//必須每次新開闢一個根節點
                    root.left=treeNode_left;//構建左子樹
                    root.right=treeNode_right;//構建右子樹
                    resList.add(root);
                }
            }
        }
        return resList;
    }
}

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章