欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Leetcode题Binary Search: 222/230/240/275/278/300,Python多种解法(十五)

程序员文章站 2024-01-14 12:02:46
...

前文

  继上篇math后,我们加快刷的速度,本期分享Binary Search的题,对于重复的题就直接跳过了!

222. Count Complete Tree Nodes


# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    """
    题意是求完全二叉树的节点数,参考博文:https://www.cnblogs.com/yrbbest/p/4993469.html
    完全二叉树即是除了最后一行节点不满,其他都是满的,而且最后一行是从左至右依次满的;满二叉树则是子节点要么满要么不满,
    该解法就是利用二者特性来做的,先定义一个求树高度的函数(求高度往左子树找),然后分别求得左子树和右子树的高度,如果二者相等,则左子树是
    满二叉树,右子树是完全二叉树;如果不等,则右子树是满二叉树,左子树是完全二叉树
    Runtime: 64 ms, faster than 98.26% of Python online submissions for Count Complete Tree Nodes.
    Memory Usage: 27.7 MB, less than 57.43% of Python online submissions for Count Complete Tree Nodes.
    """
    def countNodes(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        count = 0
        while root:
            l ,r = map(self.getHeight ,(root.left ,root.right))
            if l== r:
                count += 2 ** l
                root = root.right
            else:
                count += 2 ** r
                root = root.left
        return count

    def getHeight(self, root):
        height = 0
        while root:
            height += 1
            root = root.left
        return height

230. Kth Smallest Element in a BST


# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    """
    题意是求BST中第k小的树节点
    BST即binary search tree,树节点满足左子树小于该节点小于右子树,所以中序遍历后就可以得到有序列表
    中序遍历即:左子树→根节点→右子树,所以根据中序遍历写得递归代码如下
    Runtime: 52 ms, faster than 42.88% of Python online submissions for Kth Smallest Element in a BST.
    Memory Usage: 19.8 MB, less than 5.44% of Python online submissions for Kth Smallest Element in a BST.
    """
    def kthSmallest(self, root, k):
        """
        :type root: TreeNode
        :type k: int
        :rtype: int
        """
        self.k = k
        self.res = None
        self.helper(root)
        return self.res

    def helper(self ,Node):
        if not Node:
            return
        self.helper(Node.left)
        self.k -= 1
        if self.k == 0:
            self.res = Node.val
            return self.res
        self.helper(Node.right)


# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution2(object):
    """
    用非递归的方法来实现,利用到栈的数据结构
    先遍历到左子树树底,依次将左子树的所有节点压入栈,最后栈顶存放的就是最小的数,然后依次从栈推出,
    当k位于左子树的时候直接返回值即可,如果不在左子树,那就继续将右子树压入栈
    Runtime: 44 ms, faster than 77.44% of Python online submissions for Kth Smallest Element in a BST.
    Memory Usage: 19.6 MB, less than 63.94% of Python online submissions for Kth Smallest Element in a BST.
    """
    def kthSmallest(self, root, k):
        """
        :type root: TreeNode
        :type k: int
        :rtype: int
        """
        stack = []
        while root or stack:
            while root:
                stack.append(root)
                root = root.left
            root = stack.pop()
            k -= 1
            if k == 0:
                return root.val
            root = root.right

240. Search a 2D Matrix II


class Solution(object):
    """
    题意是求从上到下、从左到右升序排序的矩阵里是否存在某个值
    该题也被分到了树的分类里,该解法利用到python的any,针对每一行,any匹配是否存在即可
    看到any的源码描述: Return True if bool(x) is True for any x in the iterable.
    也即是遍历每个数,用bool(x)查看是否存在
    Runtime: 156 ms, faster than 22.01% of Python online submissions for Search a 2D Matrix II.
    Memory Usage: 15.8 MB, less than 13.81% of Python online submissions for Search a 2D Matrix II.
    """
    def searchMatrix(self, matrix, target):
        """
        :type matrix: List[List[int]]
        :type target: int
        :rtype: bool
        """
        return any(target in row for row in matrix)


class Solution2(object):
    """
    该解法从最后一行开始遍历,如果最后一行第一个数小于该值,则往右推移一列,如果对应的数大于该值,则往上推移一列;
    这两个都是依赖于题目给的从上到下、从左到右的升序排序,所以当同一行的数小于该值,则他上一行的数也必然小于该值,
    所以可以继续往下遍历
    Runtime: 44 ms, faster than 92.26% of Python online submissions for Search a 2D Matrix II.
    Memory Usage: 15.8 MB, less than 24.21% of Python online submissions for Search a 2D Matrix II.
    """
    def searchMatrix(self, matrix, target):
        """
        :type matrix: List[List[int]]
        :type target: int
        :rtype: bool
        """
        m = len(matrix)
        if m == 0:
            return False
        n = len(matrix[0])
        if n == 0:
            return False
        y = m - 1
        x = 0
        while y >= 0 and x < n:
            if matrix[y][x] == target:
                return True
            elif matrix[y][x] < target:
                x += 1
            else:
                y -= 1
        return False

275. H-Index II

274解法位于:https://blog.csdn.net/weixin_42681866/article/details/90711421


class Solution(object):
    """
    参照274的解法,取最优的二分法即可
    Runtime: 132 ms, faster than 45.22% of Python online submissions for H-Index II.
    Memory Usage: 16.5 MB, less than 57.46% of Python online submissions for H-Index II.
    """
    def hIndex(self, citations):
        """
        :type citations: List[int]
        :rtype: int
        """
        N = len(citations)
        l, r = 0, N - 1
        H = 0
        while l <= r:
            mid = l + (r - l) / 2
            H = max(H, min(citations[mid], N - mid))
            if citations[mid] < N - mid:
                l = mid + 1
            else:
                r = mid - 1
        return H

278. First Bad Version


# The isBadVersion API is already defined for you.
# @param version, an integer
# @return a bool
def isBadVersion(version):
    pass

import bisect
class Solution(object):
    """
    用python 的库bisect来实现,指定0-n这样的list区间,然后对每个数进行isBadVersion(i)判断
    这里用到了__getitem__(self, i)的魔法方法,使得区间的每个数可以用索引访问,当为false时返回结果
    Runtime: 12 ms, faster than 93.14% of Python online submissions for First Bad Version.
    Memory Usage: 11.8 MB, less than 44.40% of Python online submissions for First Bad Version.
    """
    def firstBadVersion(self, n):
        """
        :type n: int
        :rtype: int
        """
        class Wrap:
            def __getitem__(self, i):
                return isBadVersion(i)
        return bisect.bisect(Wrap(), False, 0, n)




class Solution2(object):
    """
    标准的二分法来解决,相当于是上面的解释版
    Runtime: 12 ms, faster than 93.14% of Python online submissions for First Bad Version.
    Memory Usage: 11.6 MB, less than 96.89% of Python online submissions for First Bad Version.
    """
    def firstBadVersion(self, n):
        """
        :type n: int
        :rtype: int
        """
        start = 1
        end = n
        while start <= end:
            mid = (start + end) // 2
            if isBadVersion(mid):
                if not isBadVersion(mid -1):
                    return mid
                else:
                    end = mid
            else:
                if isBadVersion(mid + 1):
                    return mid + 1
                else:
                    start = mid + 1

300. Longest Increasing Subsequence


class Solution(object):
    """
    题意是求数组的最大递增子序列,参考博文:https://blog.csdn.net/fuxuemingzhu/article/details/79820919
    通过动态规划的思想来完成,假设要求F(n)的最大子序列,可以先求得F(n-1)的,以此类推,我们知道F(1)=1即第一个数的
    最大子序列必定是1,那接下来就比较第2个数和第一个数,如果小于第1,则第2个数最大子序列也为1;如大于,则为2。同样的第三个数
    就要比较第1和第2,如果大于,则对应的数上+1.若一直小于,则跳过!
    Runtime: 976 ms, faster than 40.42% of Python online submissions for Longest Increasing Subsequence.
    Memory Usage: 12.1 MB, less than 13.58% of Python online submissions for Longest Increasing Subsequence.
    """
    def lengthOfLIS(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if not nums :return 0
        dp = [0] * len(nums)
        dp[0] = 1
        for i in range(1 ,len(nums)):
            tmax = 1
            for j in range(0 ,i):
                if nums[i] > nums[j]:
                    tmax = max(tmax ,dp[j] +1)
            dp[i] = tmax
        return max(dp)

总结

  此次分享到此,感谢观看~