123. 买卖股票的最佳时机 III
困难
给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。
**注意:**你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例 1:
输入:prices = [3,3,5,0,0,3,1,4]
输出:6
解释:在第 4 天(股票价格 = 0)的时候买入,在第 6 天(股票价格 = 3)的时候卖出,这笔交易所能获得利润 = 3-0 = 3 。
随后,在第 7 天(股票价格 = 1)的时候买入,在第 8 天 (股票价格 = 4)的时候卖出,这笔交易所能获得利润 = 4-1 = 3 。
示例 2:
输入:prices = [1,2,3,4,5]
输出:4
解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。
因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
示例 3:
输入:prices = [7,6,4,3,1]
输出:0
解释:在这个情况下, 没有交易完成, 所以最大利润为 0。
示例 4:
输入:prices = [1]
输出:0
提示:
1 <= prices.length <= 1050 <= prices[i] <= 105
动态规划
824ms 击败24.51%
class Solution:
def maxProfit(self, prices: List[int]) -> int:
if not prices:
return 0
dp = [[0 for _ in range(5)] for _ in range(len(prices))]
dp[0][0] = 0
dp[0][1] = -prices[0]
dp[0][2] = 0
dp[0][3] = -prices[0]
dp[0][4] = 0
for i in range(1, len(prices)):
dp[i][1] = max(dp[i-1][0] - prices[i], dp[i-1][1])
dp[i][2] = max(dp[i-1][1] + prices[i], dp[i-1][2])
dp[i][3] = max(dp[i-1][2] - prices[i], dp[i-1][3])
dp[i][4] = max(dp[i-1][3] + prices[i], dp[i-1][4])
return max(dp[-1][2], dp[-1][4])
nextpage
188. 买卖股票的最佳时机 IV
困难
给你一个整数数组 prices 和一个整数 k ,其中 prices[i] 是某支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。也就是说,你最多可以买 k 次,卖 k 次。
**注意:**你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例 1:
输入:k = 2, prices = [2,4,1]
输出:2
解释:在第 1 天 (股票价格 = 2) 的时候买入,在第 2 天 (股票价格 = 4) 的时候卖出,这笔交易所能获得利润 = 4-2 = 2 。
示例 2:
输入:k = 2, prices = [3,2,6,5,0,3]
输出:7
解释:在第 2 天 (股票价格 = 2) 的时候买入,在第 3 天 (股票价格 = 6) 的时候卖出, 这笔交易所能获得利润 = 6-2 = 4 。
随后,在第 5 天 (股票价格 = 0) 的时候买入,在第 6 天 (股票价格 = 3) 的时候卖出, 这笔交易所能获得利润 = 3-0 = 3 。
提示:
1 <= k <= 1001 <= prices.length <= 10000 <= prices[i] <= 1000
动态规划
class Solution:
def maxProfit(self, k: int, prices: List[int]) -> int:
if not prices:
return 0
dp = [[0 for _ in range(2*k+1)] for _ in range(len(prices))]
for i in range(2*k+1):
if i % 2 == 1:
dp[0][i] = -prices[0]
for i in range(1, len(prices)):
for j in range(1,2*k+1):
if j % 2 == 1:
dp[i][j] = max(dp[i-1][j-1] - prices[i], dp[i-1][j])
else:
dp[i][j] = max(dp[i-1][j-1] + prices[i], dp[i-1][j])
return dp[-1][-1]
nextpage
445. 两数相加 II
给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
示例1:

输入:l1 = [7,2,4,3], l2 = [5,6,4]
输出:[7,8,0,7]
示例2:
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[8,0,7]
示例3:
输入:l1 = [0], l2 = [0]
输出:[0]
列表转换法
class Solution:
def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
l1_stack = []
l2_stack = []
while l1:
l1_stack.append(l1.val)
l1 = l1.next
while l2:
l2_stack.append(l2.val)
l2 = l2.next
if len(l1_stack) < len(l2_stack):
l1_stack, l2_stack = l2_stack, l1_stack
carry = 0
for i in range(len(l1_stack)):
if len(l2_stack)-i > 0:
tmp = l1_stack[-1-i] + l2_stack[-1-i] + carry
else:
tmp = l1_stack[-1-i] + carry
l1_stack[-1-i] = tmp%10
carry = tmp//10
if carry:
l1_stack.insert(0,carry)
host = ListNode(l1_stack[0])
cur = host
for i in range(1,len(l1_stack)):
cur.next = ListNode(l1_stack[i])
cur = cur.next
return host
next page
513. 找树左下角的值
给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。
假设二叉树中至少有一个节点。
示例 1:

输入: root = [2,1,3]
输出: 1
示例 2:

输入: [1,2,3,4,null,5,6,null,null,7]
输出: 7
提示:
- 二叉树的节点个数的范围是
[1,104] -231 <= Node.val <= 231 - 1
队列法(BFS)
from typing import Optional
from collections import deque
class Solution:
def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
dq = deque()
dq.append(root)
dq.append("#")
ans = root.val
while not (len(dq) == 1 and dq[0] == "#"):
tmp = dq.popleft()
if tmp == "#":
if dq[0] != "#":
ans = dq[0].val
dq.append("#")
continue
if tmp.left:
dq.append(tmp.left)
if tmp.right:
dq.append(tmp.right)
return ans
next page
617. 合并二叉树
给你两棵二叉树: root1 和 root2 。
想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。
返回合并后的二叉树。
注意: 合并过程必须从两个树的根节点开始。
示例 1:

输入:root1 = [1,3,2,5], root2 = [2,1,3,null,4,null,7]
输出:[3,4,5,5,4,null,7]
示例 2:
输入:root1 = [1], root2 = [1,2]
输出:[2,2]
提示:
- 两棵树中的节点数目在范围
[0, 2000]内 -104 <= Node.val <= 104
递归法
# 方法一 我自己写的 非常冗余
class Solution:
def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
def merge(root1,root2,root1_parent,direction):
if root1 == None and root2 == None:
return
elif root1 == None or root2 == None:
if root2:
if direction == "left":
root1_parent.left = root2
elif direction == "right":
root1_parent.right = root2
return
root1.val += root2.val
merge(root1.left,root2.left,root1,"left")
merge(root1.right,root2.right,root1,"right")
if root1 == None:
return root2
merge(root1,root2,root1,"")
return root1
# 方法二 精简递归
class Solution:
def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
if not root1:
return root2
if not root2:
return root1
root1.val += root2.val
root1.left = self.mergeTrees(root1.left,root2.left)
root1.right = self.mergeTrees(root1.right,root2.right)
return root1
next page
1963. 使字符串平衡的最小交换次数
给你一个字符串 s ,下标从 0 开始 ,且长度为偶数 n 。字符串 恰好 由 n / 2 个开括号 '[' 和 n / 2 个闭括号 ']' 组成。
只有能满足下述所有条件的字符串才能称为 平衡字符串 :
- 字符串是一个空字符串,或者
- 字符串可以记作
AB,其中A和B都是 平衡字符串 ,或者 - 字符串可以写成
[C],其中C是一个 平衡字符串 。
你可以交换 任意 两个下标所对应的括号 任意 次数。
返回使 s 变成 平衡字符串 所需要的 最小 交换次数。
示例 1:
输入:s = "][]["
输出:1
解释:交换下标 0 和下标 3 对应的括号,可以使字符串变成平衡字符串。
最终字符串变成 "[[]]" 。
示例 2:
输入:s = "]]][[["
输出:2
解释:执行下述操作可以使字符串变成平衡字符串:
- 交换下标 0 和下标 4 对应的括号,s = "[]][][" 。
- 交换下标 1 和下标 5 对应的括号,s = "[[][]]" 。
最终字符串变成 "[[][]]" 。
示例 3:
输入:s = "[]"
输出:0
解释:这个字符串已经是平衡字符串。
提示:
n == s.length2 <= n <= 106n为偶数s[i]为'['或']'- 开括号
'['的数目为n / 2,闭括号']'的数目也是n / 2
标准题解
class Solution:
def minSwaps(self, s: str) -> int:
cnt = mincnt = 0
for ch in s:
if ch == '[':
cnt += 1
else:
cnt -= 1
mincnt = min(mincnt, cnt)
return (-mincnt + 1) // 2
我的做法(超时57/59 )
class Solution:
def minSwaps(self, s: str) -> int:
def checkEffctive(s):
i, depth = 0, 0
while i < len(s):
while i < len(s) and s[i] == "[":
i += 1
depth += 1
while i < len(s) and s[i] == "]":
i += 1
depth -= 1
if depth < 0:
return False
if depth != 0:
return False
return True
def swap(a,b):
a,b = b,a
s = list(s)
ans = 0
left = 0
right = len(s) - 1
while left < right and not checkEffctive(s):
while left < right and s[left] != "]":
left += 1
while left < right and s[right] != "[":
right -= 1
s[left], s[right] = s[right], s[left]
ans += 1
return ans
7212

被折叠的 条评论
为什么被折叠?



