LeetCode Practice(0805)

377. Combination Sum IV

Given an array of distinct integers nums and a target integer target, return the number of possible combinations that add up to target.

The test cases are generated so that the answer can fit in a 32-bit integer.

Example 1:

Input: nums = [1,2,3], target = 4
Output: 7

Solution:

class Solution {
    public int combinationSum4(int[] nums, int target) {
        int[] res = new int[target + 1];
        res[0] = 0;

        // base case
        for (int num: nums){
            if (num <= target) res[num] = 1;
        }

        for (int i = 1; i <= target; i++){
            for (int num: nums){
                if (i - num > 0){
                    res[i] += res[i - num];
                }
            }
        }

        return res[target];
    }
}

97. Interleaving String

Given strings s1, s2, and s3, find whether s3 is formed by an interleaving of s1 and s2.

An interleaving of two strings s and t is a configuration where s and t are divided into n and m non-empty substrings respectively, such that:

s = s1 + s2 + ... + sn
t = t1 + t2 + ... + tm
|n - m| <= 1
The interleaving is s1 + t1 + s2 + t2 + s3 + t3 + ... 
or 
t1 + s1 + t2 + s2 + t3 + s3 + ...

Note: a + b is the concatenation of strings a and b.

Example 1:

Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
Output: true
Explanation: One way to obtain s3 is:
Split s1 into s1 = "aa" + "bc" + "c", and s2 into s2 = "dbbc" + "a".
Interleaving the two splits, we get "aa" + "dbbc" + "bc" + "a" + "c" = "aadbbcbcac".
Since s3 can be obtained by interleaving s1 and s2, we return true.

Solution 1(Recursive Function: Time Exceed):

class Solution {
    public boolean isInterleave(String s1, String s2, String s3) {
        return next(0, 0, s1, s2, s3);
    }

    public boolean next(int pt1, int pt2, String s1, String s2, String s3){
        if (s1.length() <= pt1 || s2.length() <= pt2 || s3.length() <= pt1 + pt2){
            if (s1.length() <= pt1) return s2.substring(pt2).equals(s3.substring(pt1 + pt2));
            if (s2.length() <= pt2) return s1.substring(pt1).equals(s3.substring(pt1 + pt2));
            return false;
        }
        boolean possibility = false;
        if (s1.charAt(pt1) == s3.charAt(pt1 + pt2)){
            possibility = possibility || next(pt1 + 1, pt2, s1, s2, s3);
        }
        if (s2.charAt(pt2) == s3.charAt(pt1 + pt2)){
            possibility = possibility || next(pt1, pt2 + 1, s1, s2, s3);
        }
        return possibility;
    }
}

Solution 2(DP):

class Solution {
    public boolean isInterleave(String s1, String s2, String s3) {
        int m = s1.length(), n = s2.length();
        boolean[][] visited = new boolean[m + 1][n + 1];

        if (m + n != s3.length()) return false;

        // base case
        visited[0][0] = true;
        for (int i = 1; i <= m; i++){
            visited[i][0] = visited[i - 1][0] && s1.charAt(i - 1) == s3.charAt(i - 1);
        }
        for (int j = 1; j <= n; j++){
            visited[0][j] = visited[0][j - 1] && s2.charAt(j - 1) == s3.charAt(j - 1);
        }

        for (int i = 1; i <= m; i++){
            for (int j = 1; j <= n; j++){
                visited[i][j] = (visited[i - 1][j] && s1.charAt(i - 1) == s3.charAt(i + j - 1)) ||
                        (visited[i][j - 1] && s2.charAt(j - 1) == s3.charAt(i + j - 1));
            }
        }

        return visited[m][n];
    }
}

118. Pascal’s Triangle

Given an integer numRows, return the first numRows of Pascal’s triangle.

In Pascal’s triangle, each number is the sum of the two numbers directly above it as shown:

1
11
121
1331
14641

Example 1:

Input: numRows = 5
Output: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]

Solution:

class Solution {
    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> res = new ArrayList<>();
        if (numRows > 0){
            List<Integer> row1 = new ArrayList<>();
            row1.add(1);
            res.add(row1);
        }
        if (numRows > 1){
            List<Integer> row2 = new ArrayList<>();
            row2.add(1);
            row2.add(1);
            res.add(row2);
        }
        if (numRows < 3) return res;

        int r = 0, l = 0, current = 0;

        List<Integer> curList = new ArrayList<>();
        Stack<Integer> lastRow = new Stack<>();
        Stack<Integer> currentRow = new Stack<>();
        lastRow.push(1);
        lastRow.push(1);

        while (numRows > 2){
            currentRow.push(1);
            curList.add(1);
            while (lastRow.size() > 1) {
                r = lastRow.pop();
                l = lastRow.peek();
                current = r + l;
                currentRow.push(current);
                curList.add(current);
            }
            numRows--;
            currentRow.push(1);
            curList.add(1);
            res.add(curList);
            lastRow.clear();
            curList = new ArrayList<>();
            lastRow.addAll(currentRow);
            currentRow.clear();
        }
        return res;
    }
}

119. Pascal’s Triangle II

Given an integer rowIndex, return the rowIndexth (0-indexed) row of the Pascal’s triangle.

In Pascal’s triangle, each number is the sum of the two numbers directly above it as shown like LC 118. Pascal's Triangle I.

Example 1:

Input: rowIndex = 3
Output: [1,3,3,1]

Example 2:

Input: rowIndex = 0
Output: [1]

Solution 1: Use Function in LC 118

class Solution {
    public List<Integer> getRow(int rowIndex) {
        return generate(rowIndex + 1).get(rowIndex - 1);
    }

    public List<List<Integer>> generate(int numRows) {
        ...
        return res;
    }
}

Solution 2: Optimization

class Solution {
    public List<Integer> getRow(int rowIndex) {
        Stack<Integer> row = new Stack<>();
        Stack<Integer> next = new Stack<>();
        List<Integer> res = new ArrayList<>();
        row.push(1);
        row.push(1);
        if (rowIndex >= 0){
            res.add(1);
        }
        if (rowIndex >= 1){
            res.add(1);
        }
        if (rowIndex < 2) return res;

        int left = 0, right = 0, current = 0;
        while (rowIndex > 1){
            rowIndex--;
            res.clear();
            res.add(1);
            while (row.size() > 1){
                right = row.pop();
                left = row.peek();
                current = left + right;
                res.add(current);
                next.push(current);
            }
            res.add(1);
            next.push(1);
            row.addAll(next);
            next.clear();
        }
        return res;
    }
}

120. Triangle

Given a triangle array, return the minimum path sum from top to bottom.

For each step, you may move to an adjacent number of the row below. More formally, if you are on index i on the current row, you may move to either index i or index i + 1 on the next row.

Example 1:

Input: triangle = [[2],[3,4],[6,5,7],[4,1,8,3]]
Output: 11
Explanation: The triangle looks like:
   2
  3 4
 6 5 7
4 1 8 3
The minimum path sum from top to bottom is 2 + 3 + 5 + 1 = 11 (underlined above).

Solution:

class Solution {
    public int minimumTotal(List<List<Integer>> triangle) {
        if (triangle.size() == 1) return triangle.get(0).get(0);

        List<Integer> last = new ArrayList<>();
        List<Integer> current = new ArrayList<>();
        last.addAll(triangle.get(0));
        int min = -1, cnt = 0, minIndex = -1;

        for (int i = 1; i < triangle.size(); i++){
            min = -1;
            minIndex = -1;
            for (int j = 0; j < i + 1; j++){
                if (j == 0){
                    cnt = last.get(0) + triangle.get(i).get(0);
                } else if (j == i) {
                    cnt = last.get(i - 1) + triangle.get(i).get(j);
                } else {
                    cnt = Math.min(last.get(j - 1) + triangle.get(i).get(j),
                            last.get(j) + triangle.get(i).get(j));
                }
                if (minIndex == -1){
                    min = cnt;
                    minIndex = j;
                }
                if (min > cnt){
                    min = cnt;
                    minIndex = j;
                }
                current.add(cnt);
            }
            last.clear();
            last.addAll(current);
            current.clear();
        }
        return last.get(minIndex);
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值