LeetCode五月刷题总结

二叉树

prac98 验证二叉搜索树(中等)

给定一个二叉树,判断其是否是一个有效的二叉搜索树。

假设一个二叉搜索树具有如下特征:

节点的左子树只包含小于当前节点的数。 节点的右子树只包含大于当前节点的数。 所有左子树和右子树自身必须也是二叉搜索树。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/validate-binary-search-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

构造辅助函数helper(node,lower,higher),并采用递归左子树和递归右子树的方法。

# -*- encoding: utf-8 -*-
"""
@File    : prac98.py
@Time    : 2020/5/5 8:43 上午
@Author  : zhengjiani
@Email   : [email protected]
@Software: PyCharm
"""
# Definition for a binary tree node.
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution:
    def isValidBST(self, root: TreeNode) -> bool:
        def helper(node,lower=float('-inf'),upper=float('inf')):
            if not node:
                return True

            val = node.val
            if val <= lower or val >= upper:
                return False

            if not helper(node.val,val,upper):
                return False
            if not helper(node.val,lower,val):
                return False
            return True
        return helper(root)

prac572 另一个树的子树

给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树。s 的一个子树包括 s 的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/subtree-of-another-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

采用先序遍历转化为字符串,并判断两个字符串是否含有包含关系。

# -*- encoding: utf-8 -*-
"""
@File    : prac572.py
@Time    : 2020/5/7 3:03 下午
@Author  : zhengjiani
@Email   : [email protected]
@Software: PyCharm
"""
# Definition for a binary tree node.
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
class Solution:
    """DFS序列上做串匹配,先序遍历,加入null值"""
    def isSubtree(self, s: TreeNode, t: TreeNode) -> bool:
        ss = self.inorder(s)
        st = self.inorder(t)
        return st in ss
    #先序遍历
    def inorder(self,root):
        if not root:
            return '#'
        return '*'+str(root.val)+str(root.left)+str(root.right)

prac236 二叉树的最近公共祖先

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x
的深度尽可能大(一个节点也可以是它自己的祖先)。”

例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

最近公共祖先判别公式:
最近公共祖先(flson&&frson) || ((x==p ||x ==q)&&(flson||frson))

# -*- encoding: utf-8 -*-
"""
@File    : prac236.py
@Time    : 2020/5/10 9:29 上午
@Author  : zhengjiani
@Email   : [email protected]
@Software: PyCharm
"""
from collections import deque
# Definition for a binary tree node.
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Tree(object):
    def __init__(self):
        self.root = None
    # 使用列表构建二叉树
    def construct_tree(self,values=None):
        if not values:
            return None
        self.root = TreeNode(values[0])
        queue = deque([self.root])
        leng = len(values)
        nums = 1
        while nums < leng:
            node = queue.popleft()
            if node:
                node.left = TreeNode(values[nums]) if values[nums] else None
                queue.append(node.left)
                if nums + 1 <leng:
                    node.right = TreeNode(values[nums+1]) if values[nums+1] else None
                    queue.append(node.right)
                    nums += 1
                nums += 1
class Solution:
    """
    最近公共祖先(flson&&frson)||((x==p ||x ==q)&&(flson||frson))
    递归,时间复杂度O(N),空间复杂度O(N)N是二叉树的节点数,递归调用的栈深度取决于二叉树的高度
    """
    def __init__(self):
        self.ans = None
    def lowestCommonAncestor(self, root, p, q):
        """
        :param root: TreeNode
        :param p: TreeNode
        :param q: TreeNode
        :return:
        """
        self.dfs(root,p,q)
        return self.ans
    def dfs(self,root,p,q):
        """
        :param root: TreeNode
        :param p: TreeNode
        :param q: TreeNode
        :return: boolean
        """
        if root is None:
            return False
        lson = self.dfs(root.left,p,q)
        rson = self.dfs(root.right,p,q)
        if (lson and rson) or ((root.val == p.val or root.val == q.val) and (lson or rson)):
            self.ans = root
        return lson or rson or (root.val == p.val or root.val == q.val)

class Solution1:
    """
    存储父节点使用哈希表
    - 从根节点开始遍历整棵二叉树,用哈希表记录每个节点的父节点指针
    - 从p节点开始不断往它的祖先移动,并用数据结构记录已经访问过的祖先节点
    - 同样,再从q节点开始不断往它的祖先移动,如果有祖先已经被访问过,意味着这是p和q深度最深的公共祖先,即LCA节点
    """
    def __init__(self):
        self.parent = {}
        self.visited = set()
    def lowestCommonAncestor(self, root, p, q):
        self.dfs(root)
        while p is not None:
            self.visited.add(p.val)
            p = self.parent.get(p.val)
        while q is not None:
            if q.val in self.visited:
                return q
            q = self.parent.get(q.val)
    def dfs(self,root):
        """
        :param root: TreeNode
        :return:
        """
        if root.left is not None:
            self.parent[root.left.val] = root
            self.dfs(root.left)
        if root.right is not None:
            self.parent[root.right.val] = root
            self.dfs(root.right)


if __name__ == '__main__':
    t = Tree()
    t.construct_tree([3,5,1,6,2,0,8,None,None,7,4])
    p = TreeNode(5)
    q = TreeNode(1)
    s = Solution()
    print(s.lowestCommonAncestor(t.root,p,q).val)

数学计算

prac69 x的平方根

实现 int sqrt(int x) 函数。

计算并返回 x 的平方根,其中 x 是非负整数。

由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/sqrtx
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

# -*- encoding: utf-8 -*-
"""
@File    : prac69.py
@Time    : 2020/5/9 10:45 上午
@Author  : zhengjiani
@Email   : [email protected]
@Software: PyCharm
"""
class Solution:
    """二分查找"""
    def mySqrt(self, x: int) -> int:
        if x == 0:
            return 0
        left = 1
        right = x // 2
        while left < right:
            #取右中位数
            mid = (left + right + 1) >> 1
            square = mid * mid
            if square > x:
                right = mid - 1
            else:
                left = mid
        return left

class Solution1:
    """牛顿法
    可以得到正实数的算术平方根,将牛顿法得到的浮点数转化为整数
    思想:在迭代过程中,以直线代替曲线,用一阶泰勒展开式(即当前点的切线)代替原曲线,求直线与x轴的交点,重复这个过程直到收敛
    """
    def mySqrt(self, x: int) -> int:
        if x < 0:
            raise Exception('不能输入负数')
        if x == 0:
            return 0
        cur = 1
        while True:
            pre = cur
            cur = (cur + x/cur)/2
            if abs(cur-pre) < 1e-6:
                return int(cur)

if __name__ == '__main__':
    x = 8
    s = Solution1()
    print(s.mySqrt(x))

prac50 Pow(x,n),计算x的n次幂函数

# -*- encoding: utf-8 -*-
"""
@File    : prac50.py
@Time    : 2020/5/11 9:47 上午
@Author  : zhengjiani
@Email   : [email protected]
@Software: PyCharm
"""
class Solution:
    """快速幂算法
    测试用例设计
    - x = 0,1的情况
    - n = 0,1的情况
    - 测试n为负数的情况
    - 是否需要考虑溢出(Double数越界的情况)INT_MIN
    - 其他正常测试
    """
    def myPow(self, x: float, n: int) -> float:
        def quickMul(N):
            if N == 0:
                return 1.0
            y = quickMul(N//2)
            return y*y if N%2 == 0 else y*y*x
        return quickMul(n) if n >= 0 else 1/quickMul(-n)

class Solution1:
    """快速幂+迭代
    以x^77为例,每个额外乘的x都会被平方若干次,而这些指数1,4,8和64,恰好对应了77的二进制(1001101)2表示中的每个1
    """
    def myPow(self, x: float, n: int) -> float:
        def quickMul(N):
            ans = 1.0
            # 贡献的初始值为x
            x_contribute = x
            # 在对N进行二进制拆分的同时计算答案
            while N > 0:
                if N % 2 == 1:
                    # 如果N二进制表示的最低位为1,那么需要计入贡献
                    ans *= x_contribute
                # 将贡献不断的平方
                x_contribute *= x_contribute
                # 舍弃N二进制表示的最低位,这样我们每次只要判断最低位即可
                N // 2
            return ans
        return quickMul(n) if n >= 0 else 1.0 / quickMul(-n)
if __name__ == '__main__':
    x,n = 2.00000, 10
    s = Solution()
    print(s.myPow(x,n))

要注意测试用例边界值的设计以及整型溢出等问题,构建二叉树,将数组转化为二叉树的形式等~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章