zoukankan      html  css  js  c++  java
  • LeetCode 34. 在排序数组中查找元素的第一个和最后一个位置

    34. 在排序数组中查找元素的第一个和最后一个位置

    Difficulty: 中等

    给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。

    如果数组中不存在目标值 target,返回 [-1, -1]

    进阶:

    • 你可以设计并实现时间复杂度为 O(log n) 的算法解决此问题吗?

    示例 1:

    输入:nums = [5,7,7,8,8,10], target = 8
    输出:[3,4]
    

    示例 2:

    输入:nums = [5,7,7,8,8,10], target = 6
    输出:[-1,-1]
    

    示例 3:

    输入:nums = [], target = 0
    输出:[-1,-1]
    

    提示:

    • 0 <= nums.length <= 10<sup>5</sup>
    • -10<sup>9</sup> <= nums[i] <= 10<sup>9</sup>
    • nums 是一个非递减数组
    • -10<sup>9</sup> <= target <= 10<sup>9</sup>

    Solution

    解法一:很容易想到的思路,比较简单,遍历一次数组找到所有等于target的元素的下标索引然后找到对应最大最小的索引。需要注意的是数组所有的元素都相等的特殊情况。

    class Solution:
        def searchRange(self, nums: List[int], target: int) -> List[int]:
            if not nums:
                return [-1,-1]
            
            res = []
            for i, v in enumerate(nums):
                if v == target:
                    res.append(i)
            if not res:
                return [-1,-1]
            elif len(res) == 1:
                return [res[0],res[0]]
            else:
                return [min(res), max(res)]
    

    解法二:二分查找

    由于题目给定是的已经排序好的数组,在解法一中我们并没有利用到这个性质,利用二分查找可以降低查找的时间复杂度。在解题的过程中需要灵活运用二分查找,题目要求是找到元素的第一个和最后一个位置,而二分查找只能给出一个元素的位置索引。我们转换一下思路,找到数组中第一个大于等于该元素的下标res1,然后找到第一个大于等于(target+1)元素的下标res2,然后res2-1就是我们要找的target最后一个元素的下标。

    二分查找的时间复杂度是O(logn),该解法执行两次二分查找,符合进阶的要求。

    class Solution:
        def searchRange(self, nums: List[int], target: int) -> List[int]:
            if not nums:
                return [-1, -1]
            
            res1 = self.helper(nums, target)
            res2 = self.helper(nums, target + 1) - 1
            
            if res1 < len(nums) and nums[res1] == target:
                return [res1, res2]
            else: 
                return [-1, -1]
            
        def helper(self, nums, target):
            lo, hi = 0, len(nums)-1
            
            while lo <= hi:
                mid = (lo + hi) // 2
                if nums[mid] >= target:
                    hi = mid - 1
                else:
                    lo = mid + 1
            return lo
    
  • 相关阅读:
    STM32之ADC+步骤小技巧(英文)
    STM32之待机唤醒
    STM32_RTC君
    STM32之输入捕获以及小小应用(库)
    STM32之PWM君
    STM32之通用定时器
    STM32之看门狗(独立与窗口)
    零基础学习qt4 第七章的第一个例子
    SPI
    STM32串口中断的一些资料
  • 原文地址:https://www.cnblogs.com/swordspoet/p/14381248.html
Copyright © 2011-2022 走看看