算法题复健之路 第13 14 15 天

不好意思拖更了很久,这段时间发生了一些事情,主要也是自己摸鱼了一段时间,非常愧疚,准备认真做事了,整理好心情,接着努力,今天开始恢复更新和做题,把之前欠的先补一补。

第13天 :

42题,接雨水。

这题是最主要的学习到的思想还是一句话:

做这种任何类似与矩阵或者一个平面上的题,最好的做法就是,把每一个格子,每一个列,当成一个独立的整体去思考,像这题,我觉得思考的重点就在于,横线上的每一个格每一列,独立的去计算他能容纳的水,然后使用一个双指针就可以了。

class Solution:
    # def trap(self, height: List[int]) -> int:
    #     if not height: return 0

    #     n = len(height)

    #     leftlist = [height[0]] + [0]*(n-1)
    #     for i in range(1, n):
    #         leftlist[i] = max(leftlist[i-1], height[i])

    #     rightlist = [0]*(n-1) + [height[n-1]]
    #     for i in range(n-2, -1, -1):
    #         rightlist[i] = max(rightlist[i+1], height[i])

    #     ans = sum(min(leftlist[i], rightlist[i])-height[i] for i in range (n))

    #     return ans

    def trap(self, height:List[int]) -> int:
        if not height: return 0
        n = len(height)
        ans = 0

        leftmax = rightmax = 0
        left = 0
        right = n -1

        while left < right:
            leftmax = max(leftmax, height[left])
            rightmax = max(rightmax, height[right])

            if height[left] < height[right]:
                ans += leftmax - height[left]
                left += 1
            else:
                ans += rightmax - height[right]
                right -= 1

        return ans

也可以作为一个标准的动态规划,关系转移一样是上面的思想,每一个列的左边和右边的最大高度作为dp状态后计算。

第14天:

407 接雨水2:

import heapq
from typing import List

class Solution:
    def trapRainWater(self, heightMap: List[List[int]]) -> int:
        # 如果柱子的长或者宽小于等于2,则不能接住雨水
        m, n = len(heightMap), len(heightMap[0])
        if m <= 2 or n <= 2:
            return 0

        # 用于记录每一个已经计算过雨水体积的柱子
        visited = [[False for _ in range(n)] for _ in range(m)]

        # 用于保存能接雨水的最大高度
        heap = list()

        # 先将最外层的的一圈柱子高度放入堆中
        for i in range(m):
            for j in range(n):
                if i == 0 or i == m - 1 or j == 0 or j == n - 1:
                    visited[i][j] = True
                    heapq.heappush(heap, (heightMap[i][j], i, j))

        # 通过广度优先查找,依次遍历堆中每一个元素的邻近元素,并求出其将邻近元素的盛水体积
        result = 0
        directions = [(1, 0), (-1, 0), (0, 1), (0, -1)]

        while heap:
            # 总是取出外层最矮的柱子高度和对应的坐标,即当前木桶的最短木板的高度和坐标
            height, i, j = heapq.heappop(heap)
            # 遍历最矮柱子的周围所有元素
            for direction in directions:
                x, y = i + direction[0], j + direction[1]
                if 0 <= x < m and 0 <= y < n and not visited[x][y]:
                    # 如果内部元素小于于外层最矮的柱子,并求与其出高度差值,并将该元素的高度更新为当前高度
                    if height > heightMap[x][y]:
                        result += height - heightMap[x][y]
                        heapq.heappush(heap, (height, x, y))
                    # 如果内部元素大于外层最矮的柱子,将内部元素的高度与其坐标放入堆中
                    else:
                        heapq.heappush(heap, (heightMap[x][y], x, y))
                    # 将当前元素标记为访问过的状态
                    visited[x][y] = True
        return result

最大的收获有几点,1.heapq可以直接实现最大对最小堆,2.二维和一维一样本质上还是记住当前的坐标的最大状态最小状态然后进行计算后相加。

第15天:

207题,课程表:

就是一个深搜加一个记录是否闭环的东西,谨记深搜广搜几件套,先做判断,返回,然后假设已经解决,开搜,后面再做搜完之后的后处理和返回。

闭环这个判断有些意思,初始给0,我可以搜前面开始的时候赋予一个值例如1,后面搜完给他一个-1每个地方如果来了一次就是-1,如果闭环没去后面的话,他就被变成1了,返回False

class Solution:
    def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
        def dfs(i, adjacency, flags):
            if flags[i] == -1: return True
            if flags[i] == 1: return False
            flags[i] = 1
            for j in adjacency[i]:
                if not dfs(j, adjacency, flags): return False
            flags[i] = -1
            return True

        adjacency = [[] for _ in range(numCourses)]
        flags = [0 for _ in range(numCourses)]
        for cur, pre in prerequisites:
            adjacency[pre].append(cur)
        for i in range(numCourses):
            if not dfs(i, adjacency, flags): return False

        return True

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值