【LeetCode】力扣刷题之路
题目(202403018~20240322)
98. 验证二叉搜索树
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效二叉搜索树定义如下:
- 节点的左子树只包含小于当前节点的数。
- 节点的右子树只包含大于当前节点的数。
- 所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
输入:root = [2,1,3]
输出:true
示例 2:
输入:root = [5,1,4,null,null,3,6]
输出:false
解释:根节点的值是 5 ,但是右子节点的值是 4 。
提示:
- 树中节点数目范围在[1, 104] 内
- -231 <= Node.val <= 231 - 1
代码
方法1:递归
from typing import Optional
# 定义二叉树节点
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def isValidBST(self, root: Optional[TreeNode]) -> bool:
def helper(root, lower=- 2**31 - 1, upper=2**31):
if not root:
return True # 空树满足二叉搜索树
if root.val <= lower or root.val >= upper: # 节点不在上下界之间返回False
return False
if not helper(root.right, root.val, upper): # 递归遍历右子树,根节点为下界值,不符合条件则返回False
return False
if not helper(root.left, lower, root.val): # 递归遍历左子树,根节点为上界值,不符合条件则返回False
return False
return True # 以上条件都不满足则返回True
return helper(root) # 返回调用helper函数的结果
if __name__ == "__main__":
# 98.验证二叉搜索树 - 示例1
root = TreeNode(2)
root.left = TreeNode(1)
root.right = TreeNode(3) # 输入:root = [2, 1, 3]
s = Solution()
res = s.isValidBST(root)
print(res) # 输出: true
# 示例2
r2 = TreeNode(5)
r2.left = TreeNode(1)
r2.right = TreeNode(4)
r2.right.left = TreeNode(3)
r2.right.right = TreeNode(6) # 输入: r2 = [5,1,4,null,null,3,6]
res2 = s.isValidBST(r2)
print(res2) # 输出: false
方法2:迭代
from typing import Optional
# 定义二叉树节点
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def isValidBST(self, root: Optional[TreeNode]) -> bool:
if not root:
return True # 空树满足二叉搜索树
stack = [(root, - 2**31 - 1, 2**31)] # 初始化栈,根节点为(root, lower, upper)的元组
while stack:
root, lower, upper = stack.pop() # 弹出栈顶的元组
if not root: # 遇空跳过继续
continue
if root.val <= lower or root.val >= upper: # 节点不在上下界之间返回False
return False
stack.append((root.left, lower, root.val)) # 将左子树存栈,根节点为上界值
stack.append((root.right, root.val, upper)) # 将右子树存栈,根节点为下界值
return True
if __name__ == "__main__":
# 98.验证二叉搜索树 - 示例1
root = TreeNode(2)
root.left = TreeNode(1)
root.right = TreeNode(3) # 输入:root = [2, 1, 3]
s = Solution()
res = s.isValidBST(root)
print(res) # 输出: true
# 示例2
r2 = TreeNode(5)
r2.left = TreeNode(1)
r2.right = TreeNode(4)
r2.right.left = TreeNode(3)
r2.right.right = TreeNode(6) # 输入: r2 = [5,1,4,null,null,3,6]
res2 = s.isValidBST(r2)
print(res2) # 输出: false
方法3:中序遍历
from typing import Optional
# 定义二叉树节点
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def isValidBST(self, root: Optional[TreeNode]) -> bool:
def inorder(root):
if not root:
return []
else:
return inorder(root.left) + [root.val] + inorder(root.right)
inorder_list = inorder(root) # 中序遍历得到的列表
return inorder_list == sorted(set(inorder_list)) # 判断中序遍历结果是否满足严格递增序列
if __name__ == "__main__":
# 98.验证二叉搜索树 - 示例1
root = TreeNode(2)
root.left = TreeNode(1)
root.right = TreeNode(3) # 输入:root = [2, 1, 3]
s = Solution()
res = s.isValidBST(root)
print(res) # 输出: true
# 示例2
r2 = TreeNode(5)
r2.left = TreeNode(1)
r2.right = TreeNode(4)
r2.right.left = TreeNode(3)
r2.right.right = TreeNode(6) # 输入: r2 = [5,1,4,null,null,3,6]
res2 = s.isValidBST(r2)
print(res2) # 输出: false
134.加油站
在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。
你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。
给定两个整数数组 gas 和 cost ,如果你可以按顺序绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。
如果存在解,则保证它是唯一的。
示例 1:
输入: gas = [1,2,3,4,5], cost = [3,4,5,1,2]
输出: 3
解释:
从 3 号加油站(索引为 3 处)出发,可获得 4 升汽油。此时油箱有 = 0 + 4 = 4 升汽油
开往 4 号加油站,此时油箱有 4 - 1 + 5 = 8 升汽油
开往 0 号加油站,此时油箱有 8 - 2 + 1 = 7 升汽油
开往 1 号加油站,此时油箱有 7 - 3 + 2 = 6 升汽油
开往 2 号加油站,此时油箱有 6 - 4 + 3 = 5 升汽油
开往 3 号加油站,你需要消耗 5 升汽油,正好足够你返回到 3 号加油站。
因此,3 可为起始索引。
示例 2:
输入: gas = [2,3,4], cost = [3,4,3]
输出: -1
解释:
你不能从 0 号或 1 号加油站出发,因为没有足够的汽油可以让你行驶到下一个加油站。
我们从 2 号加油站出发,可以获得 4 升汽油。 此时油箱有 = 0 + 4 = 4 升汽油
开往 0 号加油站,此时油箱有 4 - 3 + 2 = 3 升汽油
开往 1 号加油站,此时油箱有 3 - 3 + 3 = 3 升汽油
你无法返回 2 号加油站,因为返程需要消耗 4 升汽油,但是你的油箱只有 3 升汽油。
因此,无论怎样,你都不可能绕环路行驶一周。
提示:
- gas.length == n
- cost.length == n
- 1 <= n <= 105
- 0 <= gas[i], cost[i] <= 104
代码
from typing import List
class Solution:
def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
surplus = 0 # 初始油箱剩余汽油为0升
total_surplus = 0 # 初始油箱总剩余汽油为0升
num_index = 0 # 初始加油站编号为0
for i in range(len(gas)):
surplus += gas[i] - cost[i] # 剩余汽油 = 加油 - 耗油
total_surplus += gas[i] - cost[i] # 总剩余汽油 = 总加油 - 总耗油
if surplus < 0: # 剩余汽油不足
num_index = i + 1 # 下一个站点
surplus = 0 # 剩余汽油重置0
if total_surplus < 0: # 总剩余汽油不足
return -1
return num_index
if __name__ == '__main__':
# 134.加油站 - 示例1
gas = [1, 2, 3, 4, 5]
cost = [3, 4, 5, 1, 2]
s = Solution()
res = s.canCompleteCircuit(gas, cost)
print(res) # 输出:3
# 示例2
gas = [2, 3, 4]
cost = [3, 4, 3]
res = s.canCompleteCircuit(gas, cost)
print(res) # 输出:-1