NeetCode刷题第九天(2024.12.22)

045 Car Fleet 车队

一条单车道高速公路上有n辆汽车前往同一目的地。、
给你两个整数数组position和speed ,长度都是n 。

  • position[i]是ith car的位置(以英里为单位)
  • speed[i]是ith辆车的速度(以英里每小时为单位)

目的地位于target英里位置。
一辆车不能超过它前面的另一辆车。它只能追上另一辆车,然后以与前面的车相同的速度行驶。
车队是一组非空的以相同位置和相同速度行驶的汽车。单辆车也被视为车队。
如果一辆汽车在车队到达目的地时追上车队,则该汽车被视为车队的一部分。
返回将到达目的地的不同车队的数量。

示例1:
Input: target = 10, position = [1,4], speed = [3,2]
Output: 1
解释:从 1(速度 3)和 4(速度 2)出发的汽车组成一个车队,在目的地 10 处相遇。

示例2:
Input: target = 10, position = [4,1,0,7], speed = [2,2,1,1]
Output: 3
解释:从 4 和 7 开始的汽车在位置 10 处形成车队。从 1 和 0 开始的汽车永远追不上它们前面的汽车。这样,就有3个车队将到达目的地。

解题1:
在这里插入图片描述
这里我们通过计算每辆汽车到达目的地需要多少时间,但是根据题目,如上图所示,蓝色汽车最开始以速度2行驶,当它追上绿色车的时候就以速度1行驶了,所以这里我们从距离目的地最近的那辆车开始遍历计算,以相反的顺序迭代这个道路上的车辆

class Solution:
    def carFleet(self, target: int, position: List[int], speed: List[int]) -> int:
        pair = [[p, s] for p,s in zip(position, speed)]

        stack = []
        for p, s in sorted(pair)[::-1]: # list[start:end:step],这样就可以实现列表的反转了\
            stack.append((target - p)/s)
            if len(stack) >= 2 and stack[-1] <= stack[-2]:
                stack.pop()
        return len(stack)

时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
空间复杂度: O ( n ) O(n) O(n)

046 Search a 2D Matrix 搜索二维矩阵

给定一个mxn二维整数数组matrix和一个整数target 。

  • matrix中的每一行均按非降序排序。
  • 每行的第一个整数都大于前一行的最后一个整数。

如果target存在于matrix中,则返回true ,否则返回false 。
你能写一个在 O ( l o g ( m ∗ n ) ) O(log(m * n)) O(log(mn))时间内运行的解决方案吗?

解题1:双重二分查找

class Solution:
    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        ROWS, COLS = len(matrix), len(matrix[0])

        top, bot = 0, ROWS - 1
        while top <= bot:
            row = (top + bot) // 2
            if target > matrix[row][-1]:
                top = row + 1
            elif target < matrix[row][0]:
                bot = row - 1
            else:
                break
        
        if not (top <= bot):
            return False
        row = (bot + top) // 2
        l, r = 0, COLS-1
        while l <= r:
            m = (l + r) //2
            if target > matrix[row][m]:
                l = m +1
            elif target < matrix[row][m]:
                r = m - 1
            else:
                return True
        return False

时间复杂度: O ( m l o g n ) O(mlogn) O(mlogn),这里先找到哪一行,再在这行中使用二分查找。当然还有更低的时间复杂度 O ( l o g m + l o g n ) O(logm+logn) O(logm+logn),这就是对行和列都使用二分查找的方法,双重二分查找
空间复杂度: O ( 1 ) O(1) O(1)

047 Koko Eating Bananas 科科吃香蕉

给定一个整数数组piles ,其中piles[i]是ith堆中香蕉的数量。您还会获得一个整数h ,它表示您必须吃完所有香蕉的小时数。
您可以决定每小时吃香蕉的速度k/每个小时,你可以选择一堆香蕉并从这堆香蕉中吃掉k香蕉。如果这堆香蕉少于k ,你可以吃完这堆香蕉,但不能在同一小时内吃掉另一堆香蕉。
返回最小整数k以便您可以在h小时内吃掉所有香蕉。

示例1:
Input: piles = [1,4,3,2], h = 9
Output: 2
解释:如果进食率为 2,您可以在 6 小时内吃完香蕉。如果进食率为 1,则需要 10 小时才能吃完所有香蕉(超过 h=9),因此最小进食率为 2。

示例2:
Input: piles = [25,10,23,4], h = 4
Output: 25

解题1:二分查找
对于给定了列表,吃香蕉的速度最小可以是1,最大应该是这个列表中的最大值。所以我们需要遍历的k的范围就是在这个之间。

class Solution:
    def minEatingSpeed(self, piles: List[int], h: int) -> int:
        l, r = 1, max(piles)
        res = r

        while l <= r:
            k = (l+r) // 2
            hours = 0
            for p in piles:
                hours += math.ceil(p / k)
            
            if hours <= h:
                res = min(res, k)
                r = k -1
            else:
                l = k + 1
        return res

时间复杂度: O ( n l o g m ) O(nlogm) O(nlogm)
空间复杂度: O ( 1 ) O(1) O(1)

048 Find Minimum in Rotated Sorted Array 查找旋转排序数组中的最小值

给定一个长度为n的数组,该数组最初按升序排序。现在它已经旋转了1到n次。例如,数组nums = [1,2,3,4,5,6]可能会变为:

  • [ 3 , 4 , 5 , 6 , 1 , 2 ]如果旋转4次。
  • [ 1 , 2 , 3 , 4 , 5 , 6 ]如果旋转6次。

请注意,旋转数组4次会将数组的最后四个元素移动到开头。将数组旋转6次生成原始数组。
假设旋转排序数组nums中的所有元素都是唯一的,则返回该数组的最小元素。
在O(n)时间内运行的解决方案很简单,您能编写在O(log n) time内运行的算法吗?

示例1:
Input: nums = [3,4,5,6,1,2]
Output: 1

示例2:
Input: nums = [4,5,0,1,2,3]
Output: 0

解题1:二分查找
在这里插入图片描述
这里我们首先需要比较最左侧的值是否小于中间的值,如果是的话,则表示该部分是未旋转数组的右侧部分,在这种情况下我们需要向右搜索,这里我们清楚左侧的内容,左指针放到mid+1的位置上来。可以看到在剩下的部分中,最左侧的值要小于最右侧的值,所以剩下部分的数组是已经排序好的并且没有旋转的。
在这里插入图片描述

class Solution:
    def findMin(self, nums: List[int]) -> int:
        res = nums[0]
        l, r = 0, len(nums)-1

        while l <= r:
            # 如果左侧小于右侧,说明是已经按照升序排序的
            if nums[l] < nums[r]:
                res = min(nums[l], res)
                break
            
            m = (l + r) // 2
            res = min(res, nums[m])
            if nums[m] >= nums[l]:
                l = m + 1
            else:
                r = m - 1
        return res

时间复杂度: O ( l o g n ) O(logn) O(logn)
空间复杂度: O ( 1 ) O(1) O(1)

049 Search in Rotated Sorted Array 在旋转排序数组中搜索

给定一个长度为n的数组,该数组最初按升序排序。现在它已经旋转了1到n次。例如,数组nums = [1,2,3,4,5,6]可能会变为:

  • [ 3 , 4 , 5 , 6 , 1 , 2 ]如果旋转4次。
  • [ 1 , 2 , 3 , 4 , 5 , 6 ]如果旋转6次。

给定旋转排序数组nums和整数target ,返回nums中target的索引,如果不存在则返回-1 。
您可以假设排序旋转数组nums中的所有元素都是唯一的,在O(n)时间内运行的解决方案很简单,您能编写在O(log n) time内运行的算法吗?

示例1:
Input: nums = [3,4,5,6,1,2], target = 1
Output: 4

示例2:
Input: nums = [3,5,6,0,1,2], target = 4
Output: -1

解题1:二分查找
在这里插入图片描述

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        l, r = 0, len(nums) - 1

        while l <= r:
            mid = (l + r) // 2
            if target == nums[mid]:
                return mid

            # 左侧部分,如果左侧小于中间,说明是递增部分
            if nums[l] <= nums[mid]:
                # 如果目标值大于该部分最大值,或者目标值小于该部分最小值
                if target > nums[mid] or target < nums[l]:
                    l = mid + 1
                else:
                    r = mid - 1
            # 右侧部分
            else:
                if target < nums[mid] or target > nums[r]:
                    r = mid - 1
                else:
                    l = mid + 1
        return -1           

时间复杂度: O ( l o g n ) O(logn) O(logn)
空间复杂度: O ( 1 ) O(1) O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值