LeetCode 34. Find First and Last Position of Element in Sorted Array(在排序数组中查找元素的第一个和最后一个位置)

原题

Given an array of integers nums sorted in ascending order, find the starting and ending position of a given target value.

Your algorithm’s runtime complexity must be in the order of O(log n).

If the target is not found in the array, return [-1, -1].

题目:
给定一个整数数组, 阅读按升序排序, 查找给定目标值的起始和结束位置;

算法的运行时复杂性必须是 O (log n) ;

如果在数组中找不到目标, 则返回 [-1,-1]。

Example 1:

Input: nums = [5,7,7,8,8,10], target = 8
Output: [3,4]

Example 2:

Input: nums = [5,7,7,8,8,10], target = 6
Output: [-1,-1]

My Solution

方案一

class Solution:
    def searchRange(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        if not nums:
            return [-1, -1]
        
        found = False
        index = start = len(nums)
        end = 0
        for i,count in enumerate(nums):
            if target > count:
                pass
            elif target == count:
                found = True
                index = i
                start = min(start, index)
                end = max(end, index)
            elif target < count and not found:
                return [-1,-1]
        if found:
            return [start, end]
        else:
            return [-1,-1]
        

注:这种方式也能通过,但是其实际算法时间复杂度为O(n),因为遍历了一遍list。

Reference answer

同第33题,只是稍稍变化;看到O(logn)的时间复杂度的查找,就首先想到二分查找,刚好这道题中数字是升序的,所以可以直接拿来用,但是我们要进行一点点小修改。当我们使用传统二分查找思路找到和target相等的值的索引的时候,我们继续分头向前向后循环,直到找到不等于target的值,此时就能找到我们需要的索引对。

class Solution:
    def searchRange(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        start = 0
        end = len(nums) - 1
        while start <= end:
            mid = int((start + end)/2)
            if nums[mid] == target:
                left = right = mid
                while left - 1 >= 0 and nums[left - 1] == target:
                    left -= 1
                while right + 1 < len(nums) and nums[right + 1] == target:
                    right += 1
                return [left, right]
            if nums[mid] <= target:
                start = mid + 1
            if nums[mid] > target:
                end = mid - 1
        return [-1, -1]

反思:

  1. 迭代方案(不断调用自身)与递归方法很近似,往往可以相互转化;
  2. 要熟悉掌握二分法;

猜你喜欢

转载自blog.csdn.net/Dby_freedom/article/details/82918548