leetcode 41. 缺失的第一个正数 42. 组合总和 II

leetcode 41. 缺失的第一个正数 42. 组合总和 II

41. 缺失的第一个正数

难度困难1258收藏分享切换为英文接收动态反馈

给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。

请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。

示例 1:

输入:nums = [1,2,0]
输出:3

示例 2:

输入:nums = [3,4,-1,1]
输出:2

示例 3:

输入:nums = [7,8,9,11,12]
输出:1

提示:

  • 1 <= nums.length <= 5 * 105
  • -231 <= nums[i] <= 231 - 1
# -*- coding: utf-8 -*-
# !/usr/bin/env python
# @Time    : 2021/9/29 9:38 
# @Author  : mtl
# @Desc    : ***
# @File    : 41.py
# @Software: PyCharm
from typing import List


class Solution:
    def firstMissingPositive(self, nums: List[int]) -> int:
        length = len(nums)
        for i in range(length):
            while 1 <= nums[i] <= length and nums[nums[i] - 1] != nums[i]:
                nums[nums[i] - 1], nums[i] = nums[i], nums[nums[i] - 1]
        for i in range(length):
            if nums[i] != i + 1:return i+1
        return length + 1

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

    def firstMissingPositive3(self, nums: List[int]) -> int:
        n = 0
        while n < len(nums):
            if nums[n] <= 0:
                nums.pop(n)
                continue
            if n - 1 >= 0 and nums[n] < nums[n - 1]:
                temp = nums[n]
                nums[n] = nums[n - 1]
                nums[n - 1] = temp
                n2 = n - 1
                while n2 > 0:
                    if nums[n - 1] < nums[n2 - 1]:
                        n2 -= 1
                    else:
                        break
                nums.insert(n2, temp)
                nums.pop(n)
            n += 1
        if len(nums) == 0 or nums[0] - 1 > 0 or nums[-1] <= 0:
            return 1
        for i in range(1, len(nums)):
            if nums[i] - nums[i - 1] > 1:
                return nums[i - 1] + 1
        return nums[-1] + 1

if __name__ == '__main__':
    nums = [1, 2, 0, 4, 5, 8]
    nums = [7, 8, 9, 11, 12]
    nums = [3,5,-1,4]
    #
    nums = [0]
    nums = [-1,-2]
    nums = [1,2,6,3,5,4]
    nums = [1, 4, 5, 6, 3]
    nums = [3, 4, -1, 1]
    nums = [1,2,0]
    nums = [-1,-2,-60,40,43]
    nums = [1, 2, 0]
    nums = [1]
    nums = [1,1]
    nums = [-1,4,2,1,9,10]
    #输出:3
    # a = [1,2,3]
    # a[0],a[1] = a[1],a[0]
    # print(a)
    print(Solution().firstMissingPositive(nums))
42. 接雨水

难度困难2864收藏分享切换为英文接收动态反馈

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

示例 1:

img

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 

示例 2:

输入:height = [4,2,0,3,2,5]
输出:9

提示:

  • n == height.length
  • 1 <= n <= 2 * 104
  • 0 <= height[i] <= 105

通过次数352,318

提交次数600,180

# -*- coding: utf-8 -*-
# !/usr/bin/env python
# @Time    : 2021/10/11 16:54 
# @Author  : mtl
# @Desc    : ***
# @File    : 42.py
# @Software: PyCharm
from typing import List


class Solution:

    def trap(self, height: List[int]) -> int:
        length = len(height)
        ans = left = 0
        while left < length:
            right = center = left + 1
            if left + 1 < length and height[left] > 0 and height[left + 1] < height[left]:
                while right < length:
                    if height[right] >= height[center]:
                        center = right
                    if height[right] > height[left]:
                        break
                    right += 1
                max_num = height[left]
                if center < right:
                    right = center
                if height[left] > height[right]:
                    max_num = height[right]
                for i in range(left + 1, right):
                    ans += max_num - height[i]
                left = right
            else:
                left += 1
        return ans

    def trap2(self, height: List[int]) -> int:
        length = len(height)
        ans = left = 0
        while left < length:
            right = center = left + 1
            if left + 1 < length and height[left] > 0 and height[left + 1] < height[left]:
                while right < length:
                    if height[right] >= height[center]:
                        center = right
                    if height[right] > height[left]:
                        break
                    ans += height[left] - height[right]
                    right += 1
                if center < right:
                    right = center
                    ans -= height[left] * len(height[right+1:]) - sum(height[right+1:])
                if height[left] > height[right]:
                    ans -= (height[left] - height[right]) * (right - left)
                left = right
            else:
                left += 1
        return ans

    def trap3(self, height: List[int]) -> int:
        l, r = 0, len(height) - 1
        l_max, r_max = height[0], height[r]
        ans = 0
        while l <= r:
            while l <= r and l_max <= r_max:
                ans += max(l_max - height[l], 0)
                l_max = max(l_max, height[l])
                l += 1
            while l <= r and l_max > r_max:
                ans += max(r_max - height[r], 0)
                r_max = max(r_max, height[r])
                r -= 1
        return ans

if __name__ == '__main__':

    height = [4, 2, 0, 3, 2, 5]
    # height = [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]
    height = [4,2,3]
    height = [5,5,1,7,1,1,5,2,7,6]
    print(Solution().trap3(height))
  r -= 1
        return ans

if __name__ == '__main__':

    height = [4, 2, 0, 3, 2, 5]
    # height = [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]
    height = [4,2,3]
    height = [5,5,1,7,1,1,5,2,7,6]
    print(Solution().trap3(height))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

matianlongg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值