class Solution:
def findLongestChain(self, pairs: List[List[int]]) -> int:
n = len(pairs)
pairs.sort()
dp = [1]*n
for i in range(n):
for j in range(i):
if pairs[i][0] > pairs[j][1]:
dp[i] = max(dp[i],dp[j]+1)
return max(dp)
class Solution:
def wiggleMaxLength(self, nums: List[int]) -> int:
n = len(nums)
dp = [[1]*2 for _ in range(n)] #[i][0] 这数应该比之前的数大,[i][1] 这数应该比之前的数小
ans = 1
for i in range(n):
for j in range(i):
if nums[j] < nums[i]:
dp[i][0] = max(dp[i][0],dp[j][1]+1)
if nums[j] > nums[i]:
dp[i][1] = max(dp[i][1],dp[j][0]+1)
ans = max(dp[i][0] ,dp[i][1])
return ans
错误代码:
class Solution:
def longestCommonSubsequence(self, text1: str, text2: str) -> int:
m = len(text1)
n = len(text2)
dp = [[0]*n for _ in range(m)]
for i in range(m):
for j in range(n):
if text1[i] == text2[j]:
print(text1[i])
dp[i][j] = dp[i-1][j-1] + 1
print(i-1,j-1)
else:
dp[i][j] = max(dp[i-1][j],dp[i][j-1])
return dp[m-1][n-1]
错误原因:
第一个字母相同的时候,变成dp[0][0] = dp[-1][-1] +1
正确代码:
class Solution:
def longestCommonSubsequence(self, text1: str, text2: str) -> int:
m = len(text1)
n = len(text2)
dp = [[0]*(n+1) for _ in range(m+1)]
for i in range(1,m+1):
for j in range(1,n+1):
if text1[i-1] == text2[j-1]:
dp[i][j] = dp[i-1][j-1] + 1
else:
dp[i][j] = max(dp[i-1][j],dp[i][j-1])
return dp[m][n]
超时答案:
class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
self.ans = 0
self.N = len(nums)
self.nums = nums
self.findTargethelper(target,0,[0])
return self.ans
def findTargethelper(self,target,n,res):
cur = []
for result in res:
result1 = result + self.nums[n]
result2 = result - self.nums[n]
cur.append(result1)
cur.append(result2)
res = cur
if n == self.N - 1:
for current in cur:
if current == target:
self.ans += 1
return
self.findTargethelper(target,n+1,res)
正确答案:
用dp来做:
假设加的数字和为x,减的数字和为y,那么x + y = target, x - y = sum
x = (target+sum)/2, 那么题目就变成了0 1 背包问题。选取数字使得他们的和为 (target + sum) / 2
但前提条件是, target < sum,并且x是一个整数
class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
if sum(nums) < target or (sum(nums)+target) % 2 != 0:
return 0
ans = (target + sum(nums))//2
dp = [1]+[0]*(ans)
for num in nums:
for i in range(ans,num-1,-1):
dp[i] += dp[i-num]
return dp[-1]
class Solution:
def findMaxForm(self, strs: List[str], m: int, n: int) -> int:
dp = [[0]*(n+1) for _ in range(m+1)]
for s in strs:
count0 = s.count('0')
count1 = s.count('1')
for i in range(m,count0-1,-1):
#倒序保证每个元素只遍历一次
#count0-1,遍历这个元素的时候,确定选它的情况一定是i-count0
for j in range(n,count1-1,-1):
dp[i][j] = max(dp[i][j],dp[i-count0][j-count1]+1)
return dp[-1][-1]
正序遍历:
class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
dp = [0]+[10001]*(amount)
for coin in coins:
for i in range(coin,amount+1):
dp[i] = min(dp[i],dp[i-coin]+1)
return dp[-1] if dp[-1] != 10001 else -1
class Solution:
def change(self, amount: int, coins: List[int]) -> int:
dp = [1]+[0]*amount
for coin in coins:
for i in range(coin,amount+1):
dp[i] += dp[i-coin]
return dp[-1]
按顺序完全背包问题:
class Solution:
def wordBreak(self, s: str, wordDict: List[str]) -> bool:
n = len(s)
dp = [False]*(n+1)
dp[0] = True
for i in range(1,n+1):
for word in wordDict:
l = len(word)
if(l<=i and word == s[i-l:i]):
dp[i] = dp[i] or dp[i-l]
return dp[n]