2021-12-16 每日打卡:难题精刷

2021-12-16 每日打卡:难题精刷

写在前面

“这些事儿在熟练之后,也许就像喝口水一样平淡,但却能给初学者带来巨大的快乐,我一直觉得,能否始终保持如初学者般的热情、专注,决定了在做某件事时能走多远,能做多好。” 该系列文章由python编写,所刷题目共三个来源:之前没做出来的 ;Leetcode中等,困难难度题目; 周赛题目;某个专题的经典题目,所有代码已AC。每日1-3道,随缘剖析,希望风雨无阻,作为勉励自己坚持刷题的记录。

41. 缺失的第一个正数

在这里插入图片描述
很好想到的一个思路是:我们可以将数组所有的数放入哈希表,随后从 11 开始依次枚举正整数,并判断其是否在哈希表中。

这是因为哈希表是一个可以支持快速查找的数据结构:
给定一个元素,我们可以在 O(1) 的时间查找该元素是否在哈希表中。
因此,我们可以考虑将给定的数组设计成哈希表的「替代产品」。

而充分利用一下题目条件,对于长度为N的数组,最小整数的范围只能在1~N+1中:

我们对数组进行遍历,对于数 x,如果它在 [1, N] 的范围内
那么就将数组中的第 x-1个位置(注意:数组下标从 0 开始)打上「标记」。
在遍历结束之后,如果所有的位置都被打上了标记,
那么答案是 N+1,否则答案是最小的没有打上标记的位置加 1。

但是!考虑我们想要使用原有数组的位置,就难免覆盖了后面需要的值,除非,我们制定某种规则,比如,使用负号,统一加上一个数固定的数这类。
在这里插入图片描述

class Solution:
    def firstMissingPositive(self, nums: List[int]) -> int:
        n = len(nums)
        for i in range(n):
            if nums[i] <= 0:
                nums[i] = n + 1
        
        for i in range(n):
            num = abs(nums[i])
            if num <= n:
                nums[num - 1] = -abs(nums[num - 1])
        
        for i in range(n):
            if nums[i] > 0:
                return i + 1
        
        return n + 1
        

42. 接雨水

在这里插入图片描述

  • 动态规划:对于下标 i,下雨后水能到达的最大高度等于下标 ii 两边的最大高度的最小值,下标 i 处能接的雨水量等于下标 ii 处的水能到达的最大高度减去 height[i]。请添加图片描述
class Solution:
    def trap(self, height: List[int]) -> int:
        if not height:
            return 0
        
        n = len(height)
        leftMax = [height[0]] + [0] * (n - 1)
        for i in range(1, n):
            leftMax[i] = max(leftMax[i - 1], height[i])

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

        ans = sum(min(leftMax[i], rightMax[i]) - height[i] for i in range(n))
        return ans

  • 双指针做法:
    在这里插入图片描述
class Solution:
    def trap(self, height: List[int]) -> int:
        ans = 0
        left, right = 0, len(height) - 1
        leftMax = rightMax = 0

        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

另外,今天还做了两道中等难度的题,小感悟:

  • 滑动窗口往往是从两遍遍历演变过来的,用于上一次解答对这一次有帮助
  • 对空间有要求,想原地交换,利用输入的数据结构即可!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值