[程序员代码面试指南]数组和矩阵-在数组中找到一个局部最小的位置(二分)
题目描述
定义局部最小的概念。arr长度为1时,arr[0]是局部最小。arr的长度为N(N>1)时,如果arr[0]<arr[1],那么arr[0]为局部最小。如果arr[N-1]<arr[N-2],那么arr[N-1]是局部最小。如果0<i<N-1,arr[i]<arr[i+1]&&arr[i]<arr[i-1],那么arr[i]是局部最小。
给定无序数组arr,已知arr中**任何两个相邻的数不相等**。写一个函数,只需返回arr中**任何一个**局部最小出现的位置即可。
题解
二分查找.
- 先查第一个元素/最后一个元素是不是局部最小。不是的话对l=1,r=len-2进行二分。
- 如果arr[mid]>arr[mid-1],那么区间缩小为[l,mid-1]; (因为不满足上一条,试着画一画,可判定新的区间有局部最小)
- 如果不满足上一条,且arr[mid]<arr[mid-1],那么区间缩小为[mid+1,r];
- 如果一二都不满足,那么由题意相邻的数不相等,说明arr[mid-1]<arr[mid]<arr[mid+1],mid即为所求。(由于不满足第一条,所以中间子数组一定存在局部最小,剩了一个元素一定是所求)
- 当l==r循环结束,l即为所求。
相关
这个题推翻了自己之前的看法。注意二分数组并不是数组有序时才可以使用,只要能确定二分两侧的某一侧肯定存在要找的内容,就可以使用二分查找。
时间复杂度O(logN)、额外空间复杂度为O(1).
代码
public class Main {
public static void main(String args[]) {
int[] arr= {10,9,8,9};
int localMinIdx=localMinIdx(arr);
System.out.println(localMinIdx);
}
public static int localMinIdx(int[] arr) {
if(arr.length==1) {
return 0;
}
if(arr.length==2) {
return arr[0]<arr[1]?0:1;
}
int l=1;
int r=arr.length-1;
int mid=-1;
while(l!=r) {
mid=(l+r)/2;
if(mid>mid-1) {
r=mid-1;
}
else if(mid<mid+1) {
l=mid+1;
}
else {
return mid;
}
}
return mid;
}
}
posted on 2019-05-23 22:37 coding_gaga 阅读(172) 评论(0) 编辑 收藏 举报
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
· 开发的设计和重构,为开发效率服务
· 从零开始开发一个 MCP Server!
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· Ai满嘴顺口溜,想考研?浪费我几个小时