【LEETCODE】68、動態規劃,medium級別,題目:95、120、91

package y2019.Algorithm.dynamicprogramming.medium;

/**
 * @ProjectName: cutter-point
 * @Package: y2019.Algorithm.dynamicprogramming.medium
 * @ClassName: NumDecodings
 * @Author: xiaof
 * @Description: 91. Decode Ways
 * A message containing letters from A-Z is being encoded to numbers using the following mapping:
 *
 * 'A' -> 1
 * 'B' -> 2
 * ...
 * 'Z' -> 26
 * Given a non-empty string containing only digits, determine the total number of ways to decode it.
 *
 * Example 1:
 *
 * Input: "12"
 * Output: 2
 * Explanation: It could be decoded as "AB" (1 2) or "L" (12).
 * Example 2:
 *
 * Input: "226"
 * Output: 3
 * Explanation: It could be decoded as "BZ" (2 26), "VF" (22 6), or "BBF" (2 2 6).
 * @Date: 2019/8/15 8:54
 * @Version: 1.0
 */
public class NumDecodings {

    public int solution(String s) {
        if (s == null || s.equals("") || (s.length() == 1 && s.equals("0"))) {
            return 0;
        }
        //我們發現這個串總最多一次可以使用2個字符,並且這兩個字符組成的數要小於26或等於26才行
        //那麼我們可以發先要獲取當前字符能組成的解碼數可分爲
        //dp[n] = dp[n-1] + {if(2num <= 26}{dp[n-2} 只有滿足使用最後2位數作爲解碼數字的時候才能加上不用這個2個字符可以組成的個數
        int[] dp = new int[s.length() + 1];
        dp[0] = 1;dp[1] = 1;
        char[] sc = s.toCharArray();

        for (int i = 2; i < dp.length; ++i) {
            //i用來標識取s的前i個字符,還要判斷這個字符不能是0,不然不能單個字符使用
            if (sc[i - 1] != '0') {

                dp[i] = dp[i - 1];
            }
            //判斷如果去除2個數的位置
            int l = i - 2;
            int value = Integer.valueOf(s.substring(l, i));
            if (value <= 26 && value > 0) {
                dp[i] += dp[i - 2];
            }
        }
        return dp[s.length()];
    }

    public static void main(String[] args) {
        String s = "12";
        String s2 = "226";
        String s3 = "10";

        NumDecodings fuc = new NumDecodings();

        fuc.solution(s3);

    }
}
package y2019.Algorithm.dynamicprogramming.medium;

import java.util.List;

/**
 * @ProjectName: cutter-point
 * @Package: y2019.Algorithm.dynamicprogramming.medium
 * @ClassName: MinimumTotal
 * @Author: xiaof
 * @Description: 120. Triangle
 * Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.
 *
 * For example, given the following triangle
 *
 * [
 *      [2],
 *     [3,4],
 *    [6,5,7],
 *   [4,1,8,3]
 * ]
 * The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11).
 * @Date: 2019/8/15 8:54
 * @Version: 1.0
 */
public class MinimumTotal {

    public int solution(List<List<Integer>> triangle) {
        //這題我們反向遍歷,從底往上進行遍歷最小值
        //可以得知第k行第i個數的最小路徑是minpath[k][i]=min{minpath[k+1][i], minpath[k+1][i+1]} + triangle[k][i]
        int[][] minpath = new int[triangle.size() + 1][triangle.size() + 1];
        for (int row = triangle.size() - 1; row >= 0; --row) {
            //列遍歷數據
            for (int column = 0; column < triangle.get(row).size(); ++column) {
                minpath[row][column] = Math.min(minpath[row + 1][column], minpath[row + 1][column + 1]) + triangle.get(row).get(column);
            }
        }

        return minpath[0][0];
    }
}

 

package y2019.Algorithm.dynamicprogramming.medium;

import y2019.Algorithm.common.TreeNode;

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

/**
 * @ProjectName: cutter-point
 * @Package: y2019.Algorithm.dynamicprogramming.medium
 * @ClassName: GenerateTrees
 * @Author: xiaof
 * @Description: 95. Unique Binary Search Trees II
 *
 * Given an integer n, generate all structurally unique BST's (binary search trees) that store values 1 ... n.
 *
 * Example:
 *
 * Input: 3
 * Output:
 * [
 *   [1,null,3,2],
 *   [3,2,null,1],
 *   [3,1,null,null,2],
 *   [2,1,3],
 *   [1,null,2,null,3]
 * ]
 * Explanation:
 * The above output corresponds to the 5 unique BST's shown below:
 *
 *    1         3     3      2      1
 *     \       /     /      / \      \
 *      3     2     1      1   3      2
 *     /     /       \                 \
 *    2     1         2                 3
 *
 * @Date: 2019/8/15 8:54
 * @Version: 1.0
 */
public class GenerateTrees {

    public List<TreeNode> solution(int n) {

        if (n == 0) return new ArrayList<>();

        return backtruack(1, n);
    }

    //因爲要求出所有可能性,那麼需要遞歸出所有結果
    public List<TreeNode> backtruack(int l, int r) {
        //我們需要進行操作的範圍是l->r
        List<TreeNode> res = new ArrayList<>();
        //如果l>r超過了,那麼直接返回一個空的集合,因爲這個區間不可能組成一顆樹
        if (l > r) {
            res.add(null);
            return res;
        }
        //如果l == r 那麼就返回以當前節點作爲根的樹
        if (l == r) {
            res.add(new TreeNode(l));
            return res;
        }
        //其餘情況把l->r的所有節點進行遍歷,依次作爲根節點進行組合
        List<TreeNode> leftlist, rightlist;
        for (int i = l; i <= r; ++i) {
            //依次吧第i個數作爲根的時候值
            leftlist = backtruack(l, i - 1);
            rightlist = backtruack(i + 1, r);

            //最後吧這兩個值都組合起來
            for (TreeNode lefttree : leftlist) {
                for (TreeNode righttree : rightlist) {
                    TreeNode root = new TreeNode(i); //當前根節點
                    root.left = lefttree;
                    root.right = righttree;
                    res.add(root);
                }
            }
        }

        return res;
    }
}

 

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