hot100练习-17

class Solution:def maxProfit(self, prices: List[int]) -> int:n = len(prices)f = [[0] * 2 for _ in range(n+2)]f[1][1] = -inffor i, e in enumerate(prices):f[i+2][0] = max(f[i+1][0], f[i+1][1]+e)f[i+2][1] = max(f[i+1][1], f[i][0]-e)return f[-1][0]动态规划,转移方程:
f[i + 2][0] = max(f[i + 1][0], f[i + 1][1] + p) # 不持有:保持 or 卖出
f[i + 2][1] = max(f[i + 1][1], f[i][0] - p) # 持有:保持 or 买入(需隔一天)

class Solution:def findDuplicate(self, nums: List[int]) -> int:slow = fast = 0while True:fast = nums[fast]fast = nums[fast]slow = nums[slow]if fast == slow:breakans = 0while ans != slow:ans = nums[ans]slow = nums[slow]return ans检测环的存在:
慢指针每次移动一步(
slow = nums[slow])。快指针每次移动两步(
fast = nums[nums[fast]])。如果存在环,快指针最终会追上慢指针,两者会在环内的某一点相遇。
- 找到环的入口(即重复的数字):
将一个指针(
ptr)重置到起点(索引 0),另一个指针(slow)保持在相遇点。两个指针每次移动一步,直到它们相遇。相遇点就是环的入口,也就是重复的数字。

# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = Noneclass Codec:def serialize(self, root):if not root: return "[]"res = []queue = collections.deque()queue.append(root)while queue:node = queue.popleft()if node:res.append(str(node.val))queue.append(node.left)queue.append(node.right)else: res.append("null")return "[" + ",".join(res) + "]"def deserialize(self, data):if data == "[]": return vals = data[1:-1].split(',')i = 1queue = collections.deque()root = TreeNode(int(vals[0]))queue.append(root)while queue:node = queue.popleft()if vals[i] != "null":node.left = TreeNode(int(vals[i]))queue.append(node.left)i += 1if vals[i] != "null":node.right = TreeNode(int(vals[i]))queue.append(node.right)i += 1return root# Your Codec object will be instantiated and called as such:
# ser = Codec()
# deser = Codec()
# ans = deser.deserialize(ser.serialize(root))",".join(res)是 Python 中字符串的一个方法,它的作用是将一个列表(res)中的所有字符串元素用 ,连接起来,生成一个新的字符串

class Solution:def lengthOfLIS(self, nums: List[int]) -> int:if not nums: return 0dp = [1] * len(nums)for i, e in enumerate(nums):for j in range(0, i):if nums[i] > nums[j]:dp[i] = max(dp[i], dp[j]+1)return max(dp)max(dp[i], dp[j] + 1)的意义
dp[i]的当前值可能已经被之前的 j更新过(比如 j=0时更新了一次,j=1时又可能更新)。
我们需要确保 dp[i]始终是所有可能的 dp[j] + 1中的最大值。

class Solution:def removeInvalidParentheses(self, s: str) -> List[str]:ans = set()round_brackets = s.count("(") + s.count(")")path = []mx = -1n = len(s)def dfs(i, lopen, ropen, abandoned):nonlocal mxif round_brackets - abandoned < mx:returnif i == n:if lopen == ropen:if lopen + ropen > mx:mx = lopen + ropenans.clear()ans.add("".join(path))elif lopen + ropen == mx:ans.add("".join(path))returnif s[i] == '(':path.append("(")dfs(i+1, lopen+1, ropen, abandoned)path.pop()dfs(i+1, lopen, ropen, abandoned+1)elif s[i] == ')':if ropen < lopen:path.append(")")dfs(i+1, lopen, ropen+1, abandoned)path.pop()dfs(i+1, lopen, ropen, abandoned+1)else:path.append(s[i])dfs(i+1, lopen, ropen, abandoned)path.pop()dfs(0,0,0,0)return list(ans)