题目:

已知存在一个按非降序排列的整数数组 nums ,数组中的值不必互不相同。

在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转 ,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,4,4,5,6,6,7] 在下标 5 处经旋转后可能变为 [4,5,6,6,7,0,1,2,4,4] 。

给你 旋转后 的数组 nums 和一个整数 target ,请你编写一个函数来判断给定的目标值是否存在于数组中。如果 nums 中存在这个目标值 target ,则返回 true ,否则返回 false 。

你必须尽可能减少整个操作步骤。

示例 1:

输入:nums = [2,5,6,0,0,1,2], target = 0
输出:true
示例 2:

输入:nums = [2,5,6,0,0,1,2], target = 3
输出:false

提示:

  • 1 <= nums.length <= 5000
  • -104 <= nums[i] <= 104
  • 题目数据保证 nums 在预先未知的某个下标上进行了旋转
  • -104 <= target <= 104

进阶:

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

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/search-in-rotated-sorted-array-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

注意:这里面有重复元素,对于像[1,3,1,1,1]这种数组,很难通过nums[left]和nums[mid]比较来判断两个升序区间的位置,但是可以通过比较nums[mid]与nums[left]是否相同,来排除重复数字,如果nums[mid] == nums[left]说明有重复的数字,让left向右移动来排除重复数字。

题目中说将数据进行旋转,这样的话就会将搜索区间从中间一分为二,位于中间的元素nums[mid]一定会在其中一个有序的区间中。当nums[mid]与target相等时,直接返回true。后续不等的情况,讨论mid与左边界的大小关系,分为两种情况:

1.mid的值大于等于左边界时:nums[mid] >= nums[left]

  • 此时在区间[left, mid - 1]内的元素一定是有序的,如果target在[left, mid -1]里,即nums[left] <= target < nums[mid],此时设置right = mid - 1;
  • 上一个区间的反面,target在区间[mid, right]中,left == mid;

2.mid的值小于左边界时:nums[mid] < nums[left]

  • 此时在区间[mid, right]内的元素一定是有序的,为了两种情况left和right变化一致,这里是假设如果target在[mid, right]里,即nums[mid] <= target <=nums[right],此时设置left = mid ;
  • 上一个区间的反面,target在区间[left, mid - 1]中,right == mid - 1;

注意:这里的区间存在[mid, right],为了防止区间只有两个元素的时候,向下取整会让mid一直和left相同,出现死循环,故需要变成向上取整mid = left + (right - left + 1) / 2。

java代码(left < right):

 1 class Solution {
2 public boolean search(int[] nums, int target) {
3 int left = 0, right = nums.length - 1;
4 while (left < right){
5 int mid = left + (right - left + 1) / 2;
6 if (nums[mid] == target) return true;
7 if (nums[left] == nums[mid]){
8 left++;
9 continue;
10 }
11 if (nums[mid] >= nums[left]){
12 if (target < nums[mid] && target >= nums[left]){
13 right = mid - 1;
14 }else{
15 left = mid;
16 }
17 }else{
18 if (target >= nums[mid] && target <= nums[right]){
19 left = mid;
20 }else{
21 right = mid - 1;
22 }
23 }
24 }
25 return nums[left] == target;
26 }
27 }

python代码:

 1 class Solution:
2 def search(self, nums: List[int], target: int) -> bool:
3 left, right = 0, len(nums) - 1
4 while left < right:
5 mid = left + (right - left + 1) // 2
6 if nums[mid] == target:
7 return True
8 if nums[left] == nums[mid]:
9 left += 1
10 continue
11 if nums[mid] >= nums[left]:
12 if nums[left] <= target < nums[mid]:
13 right = mid - 1
14 else:
15 left = mid
16 else:
17 if nums[mid] <= target <= nums[right]:
18 left = mid
19 else:
20 right = mid - 1
21 return True if nums[left] == target else False

java代码(left <= right):

 1 class Solution {
2 public boolean search(int[] nums, int target) {
3 int left = 0, right = nums.length - 1;
4 while (left <= right){
5 int mid = left + (right - left) / 2;
6 if (nums[mid] == target) return true;
7 if (nums[left] == nums[mid]){
8 left++;
9 continue;
10 }
11 //左边有序
12 if (nums[mid] >= nums[left]){
13 if (target < nums[mid] && target >= nums[left]){
14 right = mid - 1;
15 }else{
16 left = mid + 1;
17 }
18 }else{
19 if (target > nums[mid] && target <= nums[right]){
20 left = mid + 1;
21 }else{
22 right = mid - 1;
23 }
24 }
25 }
26 return false;
27 }
28 }

力扣81(java&python)-搜索旋转排序数组 II(中等)的更多相关文章

  1. 第81题:搜索旋转排序数组II

    一. 问题描述 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,0,1,2,2,5,6] 可能变为 [2,5,6,0,0,1,2] ). 编写一个函数来判断给定的目标值是 ...

  2. LeetCode(81): 搜索旋转排序数组 II

    Medium! 题目描述: 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,0,1,2,2,5,6] 可能变为 [2,5,6,0,0,1,2] ). 编写一个函数来判断给 ...

  3. Java实现 LeetCode 81 搜索旋转排序数组 II(二)

    81. 搜索旋转排序数组 II 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,0,1,2,2,5,6] 可能变为 [2,5,6,0,0,1,2] ). 编写一个函数来判 ...

  4. [LeetCode每日一题]81. 搜索旋转排序数组 II

    [LeetCode每日一题]81. 搜索旋转排序数组 II 问题 已知存在一个按非降序排列的整数数组 nums ,数组中的值不必互不相同. 在传递给函数之前,nums 在预先未知的某个下标 k(0 & ...

  5. 【LeetCode】81. 搜索旋转排序数组 II

    81. 搜索旋转排序数组 II 知识点:数组,二分查找: 题目描述 已知存在一个按非降序排列的整数数组 nums ,数组中的值不必互不相同. 在传递给函数之前,nums 在预先未知的某个下标 k(0 ...

  6. leetcode 33. 搜索旋转排序数组 及 81. 搜索旋转排序数组 II

    33. 搜索旋转排序数组 问题描述 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] ). 搜索一个给定 ...

  7. lintcode 中等题:搜索旋转排序数组II

    题目 搜索旋转排序数组 II 跟进“搜索旋转排序数组”,假如有重复元素又将如何? 是否会影响运行时间复杂度? 如何影响? 为何会影响? 写出一个函数判断给定的目标值是否出现在数组中. 样例 给出[3, ...

  8. LeetCode 81 - 搜索旋转排序数组 II - [二分+暴力]

    假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,0,1,2,2,5,6] 可能变为 [2,5,6,0,0,1,2] ). 编写一个函数来判断给定的目标值是否存在于数组中. ...

  9. LeetCode 81 搜索旋转排序数组II

    题目: 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,0,1,2,2,5,6] 可能变为 [2,5,6,0,0,1,2] ). 编写一个函数来判断给定的目标值是否存在于 ...

  10. LeetCode 81——搜索旋转排序数组 II

    1. 题目 2. 解答 2.1. 方法一 基于 LeetCode 33--搜索旋转排序数组 中的方法二. 当 nums[mid] = nums[right] 时,比如 [1, 1, 2, 1, 1], ...

随机推荐

  1. 简单实用算法—分布式自增ID算法snowflake(雪花算法)

    目录 算法概述 ID结构 算法特性 算法代码(C#) 算法测试 算法概述 分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先 ...

  2. python中往json中添加文件的方法

    一 前言: python中常用的一种方式,这里给大家列出来一下. 二 实例 比如,最简单的一个json文件 test_json = { "a": 1, "b": ...

  3. ETL工具-KETTLE教程实例实战3----转换(输入、输出)

    ETL工具-KETTLE教程实例实战3----转换(输入.输出) 欢迎关注笔者的公众号: java大师, 每日推送java.kettle运维等领域干货文章,关注即免费无套路附送 100G 海量学习.面 ...

  4. MediaCodec 低延时解码

    介绍 我们在使用Android的硬解进行解码时,如果是Android11以上则可以使用其特性低延迟,谷歌官方文档 以下是Android 11支持的低时延特性: ANGLE支持:Android 11引入 ...

  5. Android设备上运行live555的推流程序

    在live555使用NDK21编译出arm64-v8a和armeabi-v7a中我们编译出了v8a和v7a的可执行文件 我们可以使用testH264VideoStreamer程序进行推流 我们将tes ...

  6. android ndk生成第三方库的so方法(ndk-build,Application.mk,Android.mk)

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  7. Mac安装Tomcat的Home路径

    首先,强推mac上的一个软件Homebrew,安装好以后,再安装其他软甲就只是 "brew install 软件名"这么简单了. 正文: 我安装tomcat使用的是命令行操作的,也 ...

  8. JS(函数、作用域、预解析)

    一 函数的概念 在 JS 里面,可能会定义非常多的相同代码或者功能相似的代码,这些代码可能需要大量重复使用.虽然 for循环语句也能实现一些简单的重复操作,但是比较具有局限性,此时我们就可以使用 JS ...

  9. 探讨三维模型OBJ格式轻量化在数据存储的重要性

    探讨三维模型OBJ格式轻量化在数据存储的重要性 三维模型的OBJ格式轻量化在数据存储方面具有重要性.以下是对三维模型OBJ格式轻量化在数据存储的重要性进行浅析: 1.节省存储空间:原始的三维模型文件往 ...

  10. TP6框架--CRMEB学习笔记:项目初始化+环境配置

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 最近在研究一个基于TP6的框架CRMEB,这里分享下我的开发心得 首先要获取原始项目文件 这里是git地址 https://gitee.c ...