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))

要注意測試用例邊界值的設計以及整型溢出等問題,構建二叉樹,將數組轉化爲二叉樹的形式等~

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