0
点赞
收藏
分享

微信扫一扫

[Leetcode]习题打卡 part 2

萍儿的小确幸 2022-04-13 阅读 23
python

Offer 32 Ⅱ 从上到下打印二叉树 Ⅱ

Grade : easy

 代码展示:

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

class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if root is None:
            return []

        Queue = [root]      # 预添加根节点
        res = []            # 记录遍历的值
        while Queue:        # 遍历当前层的节点
            res.append([node.val for node in Queue])        # 当前层作为单独的一个列表添加到res
            level = []      # 用来记录下一层的节点,循环一次更新一次
            for node in Queue:      # 开始遍历当前层的节点
                if node.left:
                    level.append(node.left)
                if node.right:
                    level.append(node.right)
            # 循环结束,Queue内的节点更新为下一层的节点
            Queue = level
        return res

思路:就是一个(简单)的循环结构,主要思路在注释中做了展示。主体方法为:广度优先搜索

  • 首先根元素入队
  • 当队列不为空的时候
    • 求当前队列的长度 s_isi​
    • 依次从队列中取 s_isi​ 个元素进行拓展,然后进入下一次迭代

运行结果展示:

 

官方参考代码:

class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root: return []
        res, queue = [], collections.deque()
        queue.append(root)
        while queue:
            tmp = []
            for _ in range(len(queue)):
                node = queue.popleft()
                tmp.append(node.val)
                if node.left: queue.append(node.left)
                if node.right: queue.append(node.right)
            res.append(tmp)
        return res

相比之下代码简洁了许多,在处理size时避免了其数值变化(for循环中只会执行一次初始化,但是在条件判断那块由于poll()导致size()改变了)

如果用

for(int i = 0; i < q.size(); i++)

例如q.size()长度为3,那么

  • 第一次:i = 0,长度3,i++
  • 第二次:i = 1,长度2,i++
  • 第三次:i = 2,长度1,此次本应该进循环但是没有进去。

用图示方法,for循环里的i只能初始化一次,也就是i = 3,2,1,刚好三次。


Q 221 Maximal Square

 Grade: normal

 代码展示:

class Solution:
    def maximalSquare(self, matrix: List[List[str]]) -> int:
        m, n = len(matrix), len(matrix[0])
        dp = [[0]*n for _ in range(m)]
        for i in range(m):
            for j in range(n):
                if i==0 or j==0:
                    dp[i][j] = int(matrix[i][j])
                else:
                    if matrix[i][j] == '1':
                        dp[i][j] = min(dp[i-1][j],dp[i][j-1],dp[i-1][j-1])+1
        side = max(max(dp[i][j] for j in range(n)) for i in range(m))
        return side*side

思路:

和计算二维矩阵内正方形的个数思路一致
暴力解法:设当前遍历的i,ji,j位置为矩形的右下角,则其可能产生的最大正方形的边长可能为min(i,j)min(i,j),如果一个个判断该正方形是否全为1,整体的时间复杂度为O(m*n*min(m,n))O(m∗n∗min(m,n)),这还是在判定正方形全为O(1)O(1)的时间复杂度为1的条件下(这需要借助二维前缀和的辅助数组)
但是这样做忽略了以i,j为正方形右下角顶点与其相邻正方形的关系
注意最终返回的是正方形的面积

运行结果展示:

官方参考代码:

class Solution:
    def getWidth(self,num):  #步骤3:求一个数中连续最多的1
        w=0
        while num>0:
            num&=num<<1
            w+=1
        return w
    def maximalSquare(self, matrix: List[List[str]]) -> int:
        nums=[int(''.join(n),base=2) for n in matrix]  #步骤1:每一行当作二进制数
        res,n=0,len(nums)
        for i in range(n):   #步骤2:枚举所有的组合,temp存储相与的结果
            temp=nums[i]
            for j in range(i,n):
                temp&=nums[j]
                if self.getWidth(temp)<j-i+1:
                    break
                res=max(res,j-i+1)
        return res*res

 怎么感觉我的方法更暴力)相比耗时更短,其中有一个比较特殊的点:

当某一行与后面行相与的时候,1 的个数只可能变少,即宽度只会越变越小,当宽度(连续1的个数)小于高度的时候,会以宽度作为正方形的边长,此时高度再增加已经没有意义了,因为不可能再有最大值产生了,所以可以跳出循环,直接开始遍历下一个 start 行


Q 1502 Can Make Arithmetic Progression From Sequence

Grade: easy

 代码展示:

class Solution:
    def canMakeArithmeticProgression(self, arr: List[int]) -> bool:
        arr.sort()
        a=arr[1]-arr[0]
        if all(arr[i]-arr[i-1]==a for i in range(1,len(arr))):
            return True
        return False

2.0版本

class Solution:
    def canMakeArithmeticProgression(self, arr: List[int]) -> bool:
        arr.sort()
        return len(set([arr[i]-arr[i-1] for i in range(1,len(arr))])) == 1

实际上就越是写法不同

思路:

随到了个super 简单的,就是冒泡法排序加等差数列任意两差为一个定常数

运行结果展示:

 官方参考代码:

class Solution:
    def canMakeArithmeticProgression(self, arr: List[int]) -> bool:
        arr.sort()
        for i in range(1, len(arr) - 1):
            if arr[i] * 2 != arr[i - 1] + arr[i + 1]:
                return False
        return True

几乎完全一致好嘛,没什么好分析的

举报

相关推荐

0 条评论