leetcode34_Search for a Range

一.问题描述

Given a sorted array of integers, 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].

For example,
Given [5, 7, 7, 8, 8, 10] and target value 8,
return [3, 4].

就是给定一个有序list,找到目标target在list中的第一个和最后一个值的位置,若无则返回[-1,-1],要求时间复杂度为O(logN)。


二.代码编写

    对于有序序列,需求是对数时间复杂度的问题,第一反应就是二分法,对于这种有多个要求输出的问题,与经典的二分查找的不同就在于判断条件多了许多,代码编写的时候要非常细致,比如在while大循环的判断条件上,边界是大于等于,而非大于。因为要找到两端的两个target的值,所以会有两个左右指针,在指针移动时也要注意细节。这一题可以用迭代的思想来完成,会使代码不显得这么冗长,但效率上就不见得优于直接手写了。代码如下:

class Solution(object):
    def searchRange(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        len_nums = len(nums)
        left1=left2 = 0 # 定义两个指针对(left1,right1)和(left2,right2)
        right1=right2 = len_nums-1
        rlist = [-1,-1]
        while left1<=right1 or left2<=right2:
            if left1==left2 and right1 == right2: # 当两个指针对相同时
                mid = (left1+right1)/2
                if nums[mid]>target:
                    right1=right2=mid-1
                elif nums[mid]<target:
                    left1=left2=mid+1
                else:
                    if mid>0 and nums[mid-1]==target:
                        right1=mid-1   # 前指针对继续左移
                    else:
                        rlist[0] = mid
                        left1=-1   # 找到前target后立flag,以免后面代码继续找
                        right1=-2
                    if mid<len_nums-1 and nums[mid+1]==target:
                        left2 = mid+1
                    else:
                        rlist[1]=mid
                        left2=-3  # 找到后target后立flag,以免后面代码继续找
                        right2=-4
            elif left1 != -1:   # 两个指针对不同且前指针对未找到最左边的target
                mid1 = (left1+right1)/2
                if nums[mid1]<target:
                    left1=mid1+1
                elif nums[mid1]>target:
                    right1 = mid1-1
                elif mid1>0 and nums[mid1-1]==target:
                    right1 = mid1-1
                else:
                    rlist[0] = mid1
                    left1=-1
                    right1=-2
            elif left2 != -3:  # 两个指针对不同且后指针对未找到最右边的target
                mid2 = (left2+right2)/2
                if nums[mid2]<target:
                    left2 = mid2+1
                elif nums[mid2]>target:
                    right2 = mid2-1
                elif mid2<len_nums-1 and nums[mid2+1]==target:
                    left2=mid2+1
                else:
                    rlist[1]=mid2
                    left2=-3
                    right2=-4
        return rlist


运行时间:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章