Given sequence in which the subsequence's elements are in sorted order, lowest to highest, and in which the subsequence is as long as possible. This subsequence is not necessarily contiguous, or unique.
Example For [5, 4, 1, 2, 3], the LIS is [1, 2, 3], return 3 For [4, 2, 4, 5, 3, 7], the LIS is [2, 4, 5, 7], return 4
def numDecodings(self, s: str) -> int:
dp = [0] * (len(s)+1)
dp[0] = 1
dp[1] = 1 if s[0] != '0' else 0
for i in range(2, len(s)+1):
if s[i-1] != '0':
dp[i] = dp[i-1]
if 10 <= int(s[i-2:i]) <= 26:
dp[i] += dp[i-2]
return dp[len(s)]
public int longestIncreasingSubsequence(int[] nums) {
int[] f = new int[nums.length];
int ans = 0;
for (int i=1; i<nums.length; i++){
f[i] = 1; // init
for(int j=0; j<i; j++){
// 1 is f[j] itself
if(nums[j] < nums[i] && f[j]+1 > f[i]){
f[i] = f[j] + 1;
}
}
ans = Math.max(ans, f[i]);
}
return ans;
}
public int maxSubArray(int[] nums) {
int maxSum = nums[0];
int ans = nums[0];
for(int i=1; i<nums.length; i++){
maxSum = Math.max(maxSum+nums[i], nums[i]);
ans = Math.max(ans, maxSum);
}
return ans;
}
public int maxProduct(int[] nums) {
int ans=nums[0], min=nums[0], max=nums[0];
for(int i=1; i<nums.length; i++){
if(nums[i] < 0){
int tmp = min;
min = max;
max = tmp;
}
// if nums[i]==0, both max and min will be updated as 0, so disrupt the continuous
max = Math.max(nums[i], max*nums[i]);
min = Math.min(nums[i], min*nums[i]);
ans = Math.max(ans, max);
}
return ans;
}
"""
dp[i] 為數字 i 所以可構成的BST個數
dp[i] = sum of dp[j-1] * dp[i-j] for 1 <= j <= i
"""
class Solution:
def numTrees(self, n: int) -> int:
dp = [0] * (n+1)
dp[0], dp[1] = 1, 1
for i in range(2, n+1):
for j in range(1, i+1):
dp[i] += dp[j-1] * dp[i-j]
return dp[n]
def generateTrees(self, n: int) -> List[TreeNode]:
if not n: return []
return self.helper(1, n)
def helper(self, start, end):
if start > end:
return [None]
if start == end:
return [TreeNode(start)]
res = []
for i in range(start, end+1):
lefts = self.helper(start, i-1)
rights = self.helper(i+1, end)
for l in lefts:
for r in rights:
node = TreeNode(i)
node.left = l
node.right = r
res.append(node)
return res
def jobScheduling(self, startTime: List[int], endTime: List[int], profit: List[int]) -> int:
# sort by end, 如果sort by start, 有可能其中一個period 很長
# 而這個period 中間如果有更高的profit 就會搜尋不到
jobs = sorted(zip(startTime, endTime, profit), key=lambda x: x[1])
# base case
dp = [[0, 0]]
for s, e, p in jobs:
# start day+1 作為upper bound
idx = bisect.bisect(dp, [s+1])-1
# 如果每一次都update
# corner case: 有重複的start and end 的時候, 不一定拿到較大profit那個
if dp[idx][1] + p > dp[-1][1]:
dp.append([e, dp[idx][1]+p])
return dp[-1][1]