【Leetcode 每日一题】81. 搜索旋转排序数组 II

news/2025/2/3 23:12:02/

问题背景

已知存在一个按非降序排列的整数数组 n u m s nums nums,数组中的值不必互不相同。
在传递给函数之前, n u m s nums nums 在预先未知的某个下标 k ( 0 < = k < n u m s . l e n g t h ) k\ (0 <= k < nums.length) k (0<=k<nums.length) 上进行了 旋转 ,使数组变为 [ n u m s [ k ] , n u m s [ k + 1 ] , . . . , n u m s [ n − 1 ] , n u m s [ 0 ] , n u m s [ 1 ] , . . . , n u m s [ k − 1 ] ] [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]] [nums[k],nums[k+1],...,nums[n1],nums[0],nums[1],...,nums[k1]](下标 从 0 0 0 开始 计数)。例如, [ 0 , 1 , 2 , 4 , 4 , 4 , 5 , 6 , 6 , 7 ] [0,1,2,4,4,4,5,6,6,7] [0,1,2,4,4,4,5,6,6,7] 在下标 5 5 5 处经旋转后可能变为 [ 4 , 5 , 6 , 6 , 7 , 0 , 1 , 2 , 4 , 4 ] [4,5,6,6,7,0,1,2,4,4] [4,5,6,6,7,0,1,2,4,4]
给你 旋转后 的数组 n u m s nums nums 和一个整数 t a r g e t target target,请你编写一个函数来判断给定的目标值是否存在于数组中。如果 n u m s nums nums 中存在这个目标值 t a r g e t target target,则返回 t r u e true true,否则返回 f a l s e false false
你必须尽可能减少整个操作步骤。

数据约束

  • 1 ≤ n u m s . l e n g t h ≤ 5000 1 \le nums.length \le 5000 1nums.length5000
  • − 1 0 4 ≤ n u m s [ i ] ≤ 1 0 4 -10 ^ 4 \le nums[i] \le 10 ^ 4 104nums[i]104
  • 题目数据保证 n u m s nums nums 在预先未知的某个下标上进行了旋转
  • − 1 0 4 ≤ t a r g e t ≤ 1 0 4 -10 ^ 4 \le target \le 10 ^ 4 104target104

解题过程

这题是在 搜索旋转排序数组 的基础上增加了元素可重复这个条件,仍然可以参考无重复元素的实现,先找到最小值,再到相应的部分数组中去找结果。
然而之前的二分答案法是每次与数组的最后一个元素比较大小,如果遇到当前元素与数组中最后一个元素重复的情况,就没有办法确定要往那个方向继续执行了。
考虑到如果有重复元素出现上述情况,它们会在旋转之后分布在数组两头。
这时候可以反复比较范围左边界的元素和数组中最后一个元素,发现重复时就将范围中的首个元素去掉。
可能会出现两种情况,去掉的这个是要查找的目标,那它还有一个重复值在数组末尾,不影响结果;去掉的这个不是要查找的目标,那就无所谓了,也不影响结果。

这道题属于是经典的为了考知识点而一味地加限制,评价为出题把脑子出坏了。
道理很简单,去掉重复元素使得范围上可用二分查找这个过程,时间复杂度是 O ( N ) O(N) O(N) 这个量级的。
这就导致了,整个算法是无法达到 O ( l o g N ) O(logN) O(logN) 这样的水平了。
既然如此,还费劲巴拉的二分什么二分,直接遍历数组同样也只是需要 O ( N ) O(N) O(N) 的时间。

具体实现

二分查找

class Solution {public boolean search(int[] nums, int target) {int n = nums.length;int left = 0, right = n - 1;// 去掉二分范围内首尾的重复元素,注意 left != n - 1 这个条件,别把所有元素都去掉了while (left != n - 1 && nums[left] == nums[n - 1]) {left++;}// Leetcode 33.搜索旋转排序数组int minIndex = findMin(nums, left, right);if (target > nums[n - 1]) {return binarySearch(nums, target, 0, minIndex);}return binarySearch(nums, target, minIndex, n);}// Leetcode 153.找到数组中的最小值private int findMin(int[] nums, int left, int right) {int n = nums.length;while(left < right) {int mid = left + ((right - left) >> 1);if (nums[mid] > nums[n - 1]) {left = mid + 1;} else {right = mid;}}return left;}// Leetcode 35.搜索插入位置private boolean binarySearch(int[] nums, int target, int left, int right) {while (left < right) {int mid = left + ((right - left) >> 1);if (nums[mid] < target) {left = mid + 1;} else {right = mid;}}return nums[left] == target;}
}

直接遍历

class Solution {public boolean search(int[] nums, int target) {for (int num : nums) {if (num == target) {return true;}}return false;}
}

http://www.ppmy.cn/news/1569079.html

相关文章

北京大学与智元机器人联合实验室发布OmniManip:显著提升机器人3D操作能力

近年来视觉语⾔基础模型&#xff08;Vision Language Models, VLMs&#xff09;在多模态理解和⾼层次常识推理上⼤放异彩&#xff0c;如何将其应⽤于机器⼈以实现通⽤操作是具身智能领域的⼀个核⼼问题。这⼀⽬标的实现受两⼤关键挑战制约&#xff1a;1. VLM 缺少精确的 3D 理解…

揭秘算法 课程导读

目录 一、老师介绍 二、课程目标 三、课程安排 一、老师介绍 学问小小谢 我是一个热爱分享知识的人&#xff0c;我深信知识的力量能够启迪思考&#xff0c;丰富生活。 欢迎每一位对知识有渴望的朋友&#xff0c;如果你对我的创作感兴趣&#xff0c;或者我们有着共同的兴趣点&…

基于OSAL的嵌入式裸机事件驱动框架——整体架构调度机制

参考B站up主【架构分析】嵌入式祼机事件驱动框架 感谢大佬分享 任务ID &#xff1a; TASK_XXX TASK_XXX 在系统中每个任务的ID是唯一的&#xff0c;范围是 0 to 0xFFFE&#xff0c;0xFFFF保留为SYS_TSK_INIT。 同时任务ID的大小也充当任务调度的优先级&#xff0c;ID越大&#…

本地缓存~

前言 Caffeine是使用Java8对Guava缓存的重写版本&#xff0c;在Spring Boot 2.0中取而代之&#xff0c;基于LRU算法实现&#xff0c;支持多种缓存过期策略。 以下摘抄于https://github.com/ben-manes/caffeine/wiki/Benchmarks-zh-CN 基准测试通过使用Java microbenchmark ha…

2025年01月31日Github流行趋势

项目名称&#xff1a;Qwen2.5项目地址url&#xff1a;https://github.com/QwenLM/Qwen2.5项目语言&#xff1a;Shell历史star数&#xff1a;13199今日star数&#xff1a;459项目维护者&#xff1a;jklj077, JustinLin610, bug-orz, huybery, JianxinMa项目简介&#xff1a;Qwen…

Nginx前端后端共用一个域名如何配置

在 Nginx 中配置前端和后端共用一个域名的情况&#xff0c;通常是通过路径或子路径将请求转发到不同的服务。以下是一个示例配置&#xff0c;假设&#xff1a; 前端静态文件在 /var/www/frontend/。 后端 API 服务运行在 http://127.0.0.1:5000。 域名是 example.com&#xff…

Mono里运行C#脚本39—mono_jit_runtime_invoke函数

当脚本MonoEmbed里的Main ()函数JIT编译完成之后,那么就需要在C代码里运行受托管的代码,即是C#的代码。要运行托管的代码,这是需要初始化一个运行环境,以便把参数从C代码传送给托管代码,又需要从托管代码返回值传送回到C代码。 在这里是通过函数mono_jit_runtime_invoke来…

SSRF 漏洞利用 Redis 实战全解析:原理、攻击与防范

目录 前言 SSRF 漏洞深度剖析 Redis&#xff1a;强大的内存数据库 Redis 产生漏洞的原因 SSRF 漏洞利用 Redis 实战步骤 准备环境 下载安装 Redis 配置漏洞环境 启动 Redis 攻击机远程连接 Redis 利用 Redis 写 Webshell 防范措施 前言 在网络安全领域&#xff0…