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);
}
}