C++ 二分查找算法:山脉数组中查找目标值

题目

给你一个 山脉数组 mountainArr,请你返回能够使得 mountainArr.get(index) 等于 target 最小 的下标 index 值。
如果不存在这样的下标 index,就请返回 -1。
何为山脉数组?如果数组 A 是一个山脉数组的话,那它满足如下条件:
首先,A.length >= 3
其次,在 0 < i < A.length - 1 条件下,存在 i 使得:
A[0] < A[1] < … A[i-1] < A[i]
A[i] > A[i+1] > … > A[A.length - 1]
你将 不能直接访问该山脉数组,必须通过 MountainArray 接口来获取数据:
MountainArray.get(k) - 会返回数组中索引为k 的元素(下标从 0 开始)
MountainArray.length() - 会返回该数组的长度

分析

分三步。

寻找最后一个nums[mid-1]<nums[mid]的mid,当长度大于等于2是,mid-1是左子数组最后一个元素,mid是右子数组第一个元素,两个子数组都不为空,所以索引不会非法。
升序中寻找目标数,不一定存在
降序中寻找目标值,不一定存在

代码

核心代码

class Solution {
public:
int findInMountainArray(int target, MountainArray& mountainArr) {
int iTopIndex = TopIndex(mountainArr);
//左边找
{
int left = 0, right = iTopIndex;//左开右闭
while (right - left > 1)
{
const auto mid = left + (right - left) / 2;
const int midValue = mountainArr.get(mid);
if (midValue == target)
{
return mid;
}
else if (midValue < target)
{
left = mid;
}
else
{
right = mid;
}
}
if( mountainArr.get(left) == target)
{
return left;
}
}
{//右边找
int left = iTopIndex, right = mountainArr.length();//左开右闭
while (right - left > 1)
{
const auto mid = left + (right - left) / 2;
std::cout << mid << " ";
const int midValue = mountainArr.get(mid);
if (midValue == target)
{
return mid;
}
else if (midValue < target)
{
right = mid;
}
else
{
left = mid;
}
}
if( mountainArr.get(left) == target)
{
return left;
}
return -1;
}
return iTopIndex;
}
int TopIndex( MountainArray& mountainArr)
{
int left = 0, right = mountainArr.length();
while (right - left > 1)
{
const auto mid = left + (right - left) / 2;
if (mountainArr.get(mid - 1) < mountainArr.get(mid))
{
left = mid;
}
else
{
right = mid;
}
}
return left;
}
};

小幅优化后的代码

左半边寻找,可以理解为:寻找最后一个<=
右半边寻找,可以理解为:寻找最后一个>=
class Solution {
public:
int findInMountainArray(int target, MountainArray& mountainArr) {
int iTopIndex = TopIndex(mountainArr);
//左边找
{
int left = 0, right = iTopIndex;//左开右闭
while (right - left > 1)
{
const auto mid = left + (right - left) / 2;
const int midValue = mountainArr.get(mid);
if (midValue <= target)
{
left = mid;
}
else
{
right = mid;
}
}
if (mountainArr.get(left) == target)
{
return left;
}
}
{//右边找
int left = iTopIndex, right = mountainArr.length();//左开右闭
while (right - left > 1)
{
const auto mid = left + (right - left) / 2;
std::cout << mid << " ";
const int midValue = mountainArr.get(mid);
if (midValue >= target)
{
left = mid;
}
else
{
right = mid;
}
}
if (mountainArr.get(left) == target)
{
return left;
}
return -1;
}
return iTopIndex;
}
int TopIndex(MountainArray& mountainArr)
{
int left = 0, right = mountainArr.length();
while (right - left > 1)
{
const auto mid = left + (right - left) / 2;
if (mountainArr.get(mid - 1) < mountainArr.get(mid))
{
left = mid;
}
else
{
right = mid;
}
}
return left;
}
};

2022年12月旧代码

class Solution {
public:
int findInMountainArray(int target, MountainArray &mountainArr) {
int iMaxK = FindMax(mountainArr,0, mountainArr.length());
int iLeft = FindLeft(mountainArr, 0, iMaxK + 1, target);
if (-1 != iLeft)
{
return iLeft;
}
return FindRight(mountainArr, iMaxK, mountainArr.length(), target);
}
int FindMax( MountainArray &mountainArr, int iMin, int iMax)
{
if (iMax - iMin <= 1)
{
return iMin;
}
int iMid = (iMin + iMax) / 2;
if (mountainArr.get(iMid - 1) < mountainArr.get(iMid))
{
return FindMax(mountainArr, iMid, iMax);
}
return FindMax(mountainArr, iMin, iMid);
}
int FindLeft(MountainArray &mountainArr, int iMin, int iMax, int target)
{
if (iMax - iMin <= 1)
{
if (mountainArr.get(iMin) == target)
{
return iMin;
}
return -1;
}
int iMid = (iMin + iMax) / 2;
const int iMidValue = mountainArr.get(iMid);
if (iMidValue == target)
{
return iMid;
}
if (iMidValue < target)
{
return FindLeft(mountainArr, iMid, iMax,target);
}
return FindLeft(mountainArr, iMin, iMid, target);
}
int FindRight(MountainArray &mountainArr, int iMin, int iMax, int target)
{
if (iMax - iMin <= 1)
{
if (mountainArr.get(iMin) == target)
{
return iMin;
}
return -1;
}
int iMid = (iMin + iMax) / 2;
const int iMidValue = mountainArr.get(iMid);
if (iMidValue == target)
{
return iMid;
}
if (iMidValue < target)
{
return FindLeft(mountainArr, iMin, iMid, target);
}
return FindLeft(mountainArr, iMid, iMax, target);
}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/143341.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

利用Nextcloud搭建企业私有云盘系统

利用Nextcloud搭建企业私有云盘系统 1. 场景介绍2. 环境准备3. 安装NextCloud4. 系统功能验证 1. 场景介绍 Nextcloud是一款免费开源的私有云存储系统&#xff0c;采用PHPMySQL开发&#xff0c;提供了多个同步客户端支持多种设备访问&#xff0c;使用Nextcloud可以快速便捷地搭…

调用一个RPC服务的三重境界

开篇词 毫无疑问微服务架构是目前最主流的大型互联网应用系统架构方式&#xff0c;因为一个大型系统被拆分为若干个子应用&#xff0c;故子应用之间相互调用进行数据读写这件事情变得像呼吸一样普遍。每个一个程序员都能够写代码实现一个RPC服务的调用&#xff0c;但不同的实现…

天软特色因子看板 (2023.11 第10期)

该因子看板跟踪天软特色因子A05006(近一月单笔流入流出金额之比(%)该因子为近一个月单笔流入流出金额之比(%)均值因子&#xff0c;用以刻画 市场日内分时成交中流入、流出成交金额的差异性特点&#xff0c;发掘市场主力资金的作用机制。 今日为该因子跟踪第10期&#xff0c;跟踪…

HarmonyOS 学习记录

时光荏苒,岁月如梭,韶华不负,未来可期。转眼间已经30岁了&#xff0c;学习的重要性不言而喻&#xff0c;在接下来的日子里记录下自己学习HarmonyOS的过程。增加一下知识储备&#xff0c;防患于未然嘛 不得不说华为的开发文档写的不错&#xff0c;开发工具直接安装后自动配置环境…

【Ubuntu】Windows访问Ubuntu时“需要认证”界面卡住

情况描述 基本情况 本地电脑&#xff1a;Microsoft Windows [版本 10.0.19045.3570] 远程电脑&#xff1a;Ubuntu 20.04.6 LTS 远程电脑安装辅助远程工具&#xff1a;xrdp 0.9.12 问题描述&#xff1a;认证页面输入密码&#xff0c;点击认证以后认证按钮不可点击&#xff0c;无…

Vue修饰符(Vue事件修饰符、Vue按键修饰符)

目录 前言 Vue事件修饰符 列举较常用的事件修饰符 .stop .prevent .capture .once Vue按键修饰符 四个特殊键 获取某个键的按键修饰符 前言 本文介绍Vue修饰符&#xff0c;包括Vue事件修饰符以及按键修饰符 Vue事件修饰符 列举较常用的事件修饰符 .stop: …

半平面求交 - 洛谷 - P3194 [HNOI2008] 水平可见直线

欢迎关注更多精彩 关注我&#xff0c;学习常用算法与数据结构&#xff0c;一题多解&#xff0c;降维打击。 往期相关背景点击前往 题目大意 题目链接 https://www.luogu.com.cn/problem/P3194 在直角坐标系中给定一些直线&#xff0c;然后从Y轴无穷大处往0处看&#xff0c;…

EDA实验------数控分频器设计(QuartusII)

目录 一、实验目的 二、实验原理 三、实验内容 四、实验步骤 五、注意事项 六、思考题 七、实验过程 分频器的基本原理 什么是分频器&#xff1f; 如何去分频&#xff1f; 1.创建新项目 2.创建Verilog文件&#xff0c;写入代码 3.连接电路 ​编辑 锁相环的创建 4…

ubuntu18.04安装google浏览器

下载google安装包 wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb 安装google浏览器 sudo dpkg -i google-chrome-stable_current_amd64.deb 执行安装 sudo apt-get -f install 启动浏览器 在应用程序中找到google图标点击运行

物联网AI MicroPython学习之语法 GPIO输入输出模块

学物联网&#xff0c;来万物简单IoT物联网&#xff01;&#xff01; GPIO 介绍 模块功能: GPIO通用输入输出。 接口说明 GPIO - 构建GPIO对象 函数原型&#xff1a;Pin(port, dir , pull)参数说明&#xff1a; 参数类型必选参数&#xff1f;说明portintY对应开发板的引脚号…

快速去除Excel表格密码,的工作更高效

你忘记了Excel表格的密码&#xff1f;别担心&#xff0c;有一个非常简单的方法来帮助你找回密码并解除限制。具体步骤如下&#xff1a;首先&#xff0c;打开浏览器并百度搜索【密码帝官网】。然后&#xff0c;在搜索结果中点击“立即开始”&#xff0c;进入密码帝官网的用户中心…

HTML转义字符

HTML&#xff0c;XML文件中存在部分字符作为标志字符无法作为文本内容使用&#xff0c;如< >&#xff0c;如果想在文本中输出&#xff0c;可使用转义字符。 < 的转义字符为 " < " > 的转义字符为 " > " <TextView.... ....android:t…

基础课4——客服中心管理者面临的挑战

客服管理者在当今的数字化时代也面临着许多挑战。以下是一些主要的挑战&#xff1a; 同行业竞争加剧&#xff1a;客服行业面临着来自同行业的竞争压力。为了获得竞争优势&#xff0c;企业需要不断提高自身的产品和服务质量&#xff0c;同时还需要不断降低成本、提高效率。然而…

【入门Flink】- 11Flink实现动态TopN

基本处理函数&#xff08;ProcessFunction&#xff09; stream.process(new MyProcessFunction())方法需要传入一个 ProcessFunction 作为参数&#xff0c;ProcessFunction 不是接口 &#xff0c; 而是一个抽象类 &#xff0c;继承了AbstractRichFunction&#xff0c;所有的处…

Oracle(2-2)Oracle Net Architecture

文章目录 一、基础知识1、Oracle Net Connections Oracle网络连接2、C/S Application Connection C/S应用程序连接3、OSI Communication Layers OSI通信层4、Oracle Protocol Support Oracle协议支持5、B/S Application Connections B/S应用程序连接6、TwoTypes JDBC Drivers 两…

成为AI产品经理——成长路径

注&#xff1a;这一节的课程分为对已经从业产品经理业务转型的人群和想要进入到AI产品行业的人群两部分&#xff0c;我这里针对自己的情况只说明了第二部分&#xff0c;如果有需要了解其他的成长路径方式的朋友请自行观看刘老师的课程。 1.持续了解AI行业 你需要持之以恒的了…

Vue 2学习(路由、history 和 hash 模式、)-day014

一、路由简介 路由&#xff08;route&#xff09;就是一组 key-value 的对应关系多个路由&#xff0c;需要经过路由器&#xff08;router&#xff09;的管理 在 Vue 中也有路由&#xff0c;Vue 中的路由主要是通过 vue-rounter 这个插件库来实现&#xff0c;它的作用就是专门用…

力扣双周赛 -- 117(容斥原理专场)

class Solution { public:long long c2(long long n){return n > 1? n * (n - 1) / 2 : 0;}long long distributeCandies(int n, int limit) {return c2(n 2) - 3 * c2(n - limit 1) 3 * c2(n - 2 * limit) - c2(n - 3 * limit - 1);} };

linux手写线程池-C

1.线程池原理 我们使用线程的时候就去创建一个线程&#xff0c;这样实现起来非常简便&#xff0c;但是就会有一个问题&#xff1a;如果并发的线程数量很多&#xff0c;并且每个线程都是执行一个时间很短的任务就结束了&#xff0c;这样频繁创建线程就会大大降低系统的效率&…

Python+selenium自动化测试

批量执行完用例后&#xff0c;生成的测试报告是文本形式的&#xff0c;不够直观&#xff0c;为了更好的展示测试报告&#xff0c;最好是生成HTML格式的。 unittest里面是不能生成html格式报告的&#xff0c;需要导入一个第三方的模块&#xff1a;HTMLTestRunner 一、导入HTML…