每日一题——旋转数组的最小数字(II)

news/2025/1/19 3:09:40/

旋转数组的最小数字——II

题目链接

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HfqanL7d-1691934029415)(C:\Users\HUASHUO\AppData\Roaming\Typora\typora-user-images\image-20230813204334548.png)]

注:此题是昨天旋转数组的最小数字——I的拓展延伸,昨天题目数组的条件是不会存在重复元素,而本题数组的元素可以重复,因此建议先做前面一题,进行思考,这样求解这一题的过程就会容易理解许多。


旋转数组的性质

由旋转数组的最小数字——I我们知道了:

以数组最右侧数据val为参考对象,最小值右侧的数一定小于val,最小值左边的数一定大于val

可以得到以下图像:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1LUqxiEc-1691934029415)(C:/Users/HUASHUO/AppData/Roaming/Typora/typora-user-images/image-20230813204903425.png)]

而今天这一题多了一个条件:数组中可能存在重复元素。我们需要考虑的情况又复杂了一点:

以数组最右侧数据val为参考对象,最小值右侧的数一定等于小于val,最小值左边的数一定大于等于val

我们同样用二分法来解决:

  • 同样,我们设左边界为left,右边界为right,区间的中间下标为mid

  • 如果nums[mid] > nums[right],和原来一样,最小值一定不在左侧区域,left = mid + 1

  • 如果nums[mid] < nums[right],和原来一样,最小值一定不在右侧区域(但可能就是mid位置的值),right = mid

  • 如果nums[mid]==nums[rihgt],这种情况就值得注意了,如下图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uNuvbIY4-1691934029416)(C:/Users/HUASHUO/AppData/Roaming/Typora/typora-user-images/image-20230813210527291.png)]

  • 此时,nums[mid]可能在最小值的左边,也可能在最小值的右边,因此我们不能随意地舍去mid左侧的数据或者右侧的数据。对于这种情况的处理,我们有两种方法:

方法一:

不能随意舍去mid左半部分或者右半部分是因为最小值到底是在mid的左边还是右边是不确定的,但是如果我们可以通过处理来确定最小值和mid的关系呢?

我们知道,数组旋转后,其被分割成了两串非递减数列,而令我们困扰的就是诸如这种情况:[3,3,1,3],[4,4,5,1,4,4,4,4,4]。那么我们可以删除数组前面所有等于nums[right]的元素,使数组变成诸如[1,3],[5,1,4,4,4,4]的形式,这样当nums[mid]==nums[right]这种情况出现时,mid就一定会出现在最小值的右侧mid右侧的数据也就可以删除了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-unGjeYsq-1691934029416)(C:/Users/HUASHUO/AppData/Roaming/Typora/typora-user-images/image-20230813212421862.png)]

实现代码

int minArray(int* nums, int numsSize){int left = 0;int right = numsSize - 1;//删除数组前面所有等于nums[right]的元素while (left < numsSize && nums[left] == nums[right])left++;while (left < right){int mid = (right - left) / 2 + left;//如果中间值大于最右边的值,那么最小值一定在中间值的右边if (nums[mid] > nums[right])left = mid + 1;//否则,最小值就在最右边的值的左边,也可能就是这个中间值elseright = mid;}return nums[right];
}

方法二

虽然我们不能随意舍弃mid的左半部分或者右半部分,但是我们可以确定,无论nums[right]是不是最小值,都有它的一个替代品nums[mid],因此我们可以删除最右边的数据nums[right]

实现代码

int minArray(int* nums, int numsSize){int left = 0;int right = numsSize - 1;while (left < right){int mid = (right - left) / 2 + left;//如果中间值大于最右边的值,那么最小值一定在中间值的右边if (nums[mid] > nums[right])left = mid + 1;//如果中间值小于最右边的值,那么最小值一定在中间值的左边或者就是中间值else if (nums[mid] < nums[right])right = mid;//如果中间值等于最右边的值,那么就删除最右侧元素else    right--;}return nums[left];
}

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

相关文章

C++中const,指针和引用

C中的const&#xff0c;指针和引用 在线C/C编译器&#xff0c;可以试着运行代码。 C中的const 在C语言中&#xff0c;const修饰的量称为常变量&#xff08;在编译过程中&#xff0c;const就是当成变量的编译生成指令的&#xff09;&#xff0c;不可以直接修改它的值&#xf…

DIP: Spectral Bias of DIP 频谱偏置解释DIP

On Measuring and Controlling the Spectral Bias of the Deep Image Prior 文章目录 On Measuring and Controlling the Spectral Bias of the Deep Image Prior1. 方法原理1.1 动机1.2 相关概念1.3 方法原理频带一致度量与网络退化谱偏移和网络结构的关系Lipschitz-controlle…

Oracle 使用 CONNECT_BY_ROOT 解锁层次结构洞察:在 SQL 中导航数据关系

CONNECT_BY_ROOT 是一个在 Oracle 数据库中使用的特殊函数&#xff0c;它通常用于在层次查询中获取根节点的值。在使用 CONNECT BY 子句进行层次查询时&#xff0c;通过 CONNECT_BY_ROOT 函数&#xff0c;你可以在每一行中获取根节点的值&#xff0c;而不仅仅是当前行的值。 假…

第4章:决策树

停止 当前分支样本均为同一类时&#xff0c;变成该类的叶子节点。当前分支类型不同&#xff0c;但是已经没有可以用来分裂的属性时&#xff0c;变成类别样本更多的那个类别的叶子节点。当前分支为空时&#xff0c;变成父节点类别最多的类的叶子节点。 ID3 C4.5 Cart 过拟合 缺…

SpringMVC关于SSM的整合配置步骤

&#x1f40c;个人主页&#xff1a; &#x1f40c; 叶落闲庭 &#x1f4a8;我的专栏&#xff1a;&#x1f4a8; c语言 数据结构 javaweb 石可破也&#xff0c;而不可夺坚&#xff1b;丹可磨也&#xff0c;而不可夺赤。 SSM整合 一、创建工程1.1创建Maven工程1.2工程命名1.3检查…

Java课题笔记~ ServletContext

单个Servlet的配置对象 web.xml <servlet><servlet-name>FirstServlet</servlet-name><servlet-class>com.ambow.test.FirstServlet</servlet-class><init-param><param-name>charset</param-name><param-value>utf-8&…

dubbo3-高级特性

dubbo-admin 1.dubbo-admin管理平台&#xff0c;是图形化的管理页面 2.从注册中心中获取所有的提供者/消费者进行配置管理 3.路由规则&#xff0c;动态配置&#xff0c;服务降级&#xff0c;访问控制&#xff0c;权重调整&#xff0c;负载均衡等管理功能 dubbo-admin是一个前…

client-go实战之十二:选主(leader-election)

欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码)&#xff1a;https://github.com/zq2599/blog_demos 本篇概览 本文是《client-go实战》系列的第十二篇&#xff0c;又有一个精彩的知识点在本章呈现&#xff1a;选主(leader-election)在解释什么是选主之前&…