【LeetCode】力扣刷题之路(202403018~20240322)

题目(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

  • 19
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值