go判断数组中是否存在某值_LeetCode81-搜索旋转排序数组 II

本文介绍了LeetCode第81题——搜索旋转排序数组II的解决方案。讨论了两种方法,包括直接使用`if target in nums`的简单方法和基于二分法的实现。重点在于处理数组可能存在的重复值和两段单调有序部分的分类讨论。
摘要由CSDN通过智能技术生成

0446ace159c2c25ea554a0da4a88e940.png

昨天一朋友和我推荐了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%左右。

a9fd8fcca861935024b73e2434852e34.png

方法二:

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

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

如下图所示:

f06652513e6115cf358f273e6a08cbd7.png

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

f01d8c14192cbe739cb8313443aa33e9.png

代码如下:

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%左右。如果各位读者有更好的方法还请多多分享!!!

05e67edf3d8335a2ecee6840ad022fe5.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值