LeetCode81-搜索旋转排序数组 II

昨天一朋友和我推荐了CCF考试

二话不说就报名了

不过报名费是真的有些心痛

但这个学期就是抱着一种心态

看到什么比赛就像参加

大学时期没怎么想

现在就想把之前落下的给补上


81-搜索旋转排序数组 II

假设按照升序排序的数组在预先未知的某个点上进行了旋转。

( 例如,数组 [0,0,1,2,2,5,6] 可能变为 [2,5,6,0,0,1,2] )。

编写一个函数来判断给定的目标值是否存在于数组中。若存在返回 true,否则返回 false

示例 1:

,5,6,0,0,1,2]

示例 2:

,5,6,0,0,1,2]

进阶:

  • 这是 搜索旋转排序数组 的延伸题目,本题中的 nums 可能包含重复元素。
  • 这会影响到程序的时间复杂度吗?会有怎样的影响,为什么?

思路:

本题有两种方法,第一种属于作弊法,第二种就是很常规的二分法了。

方法一:

直接使用直接使用if target in nums即可迅速得出答案。但是没有什么营养价值

代码如下:

class Solution(object):
    # 此种解法属于作弊方法,直接使用if target in nums
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: bool
        """
        return True if target in nums else False


if __name__ == "__main__":
    nums = [2, 5, 6, 0, 0, 1, 2]
    target = 0
    is_contain = Solution().search(nums, target)
    print(is_contain)

不过执行效率也是不高,只有10%左右。

方法二:

该方法是基于常规的二分法来实现的,我们知道凡是碰到这种数组或矩阵里找某值的题目,大部分是采用二分法的,因为其效率快,本题亦是如此。不过本题有两个陷阱,一是给定列表是两段分别单调有序的数组合并起来的,这就会产生多种分类情况。因为我们知道使用二分法的先决条件就是:给定序列单调有序,在此题中就相当于是中间有一部分断层了。二是给定列表中可能存在重复值,如何去重也是一个需要考虑的问题。问题主要是这两个,至于怎么解决,我们一个一个来。

先说第二个问题吧,这个解决起来比较简单。

如下图所示:

 此时第二个问题就解决了,再来说说第一个问题。说个题外话哈,其实你会发现本题就是个分类讨论的题目,只要把各种情况给考虑到了,答案自然就出来了。现在的关键就是如何确定分类的条件,大的方向还是将nums[mid]与nums[start],nums[end]作比较,但每个大比较里面还有各种小情况,具体见下图所示:

 

代码如下:

class Solution(object):
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: bool
        """
        # 分别定义nums数组的首尾指针
        start = 0
        end = len(nums)-1
        while start <= end:
            mid = (start+end)//2
            if nums[mid] == target:
                return True
            # 此时start到end之间表示的元素刚好为单增序列
            if nums[mid] == nums[start]:
                start += 1
            elif nums[mid] == nums[end]:
                end -= 1
            elif nums[mid] > nums[start]:
                if nums[start] <= target < nums[mid]:
                    end = mid - 1
                else:
                    start = mid + 1
            elif nums[mid] < nums[end]:
                if nums[end] >= target > nums[mid]:
                    start = mid + 1
                else:
                    end = mid - 1
        return False


if __name__ == "__main__":
    nums = [5, 1, 3]
    target = 3
    is_contain = Solution().search(nums, target)
    print(is_contain)

执行效率和方法一差不多,在10%左右。如果各位读者有更好的方法还请多多分享!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

学习的学习者

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

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

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

打赏作者

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

抵扣说明:

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

余额充值