【算法】【优选算法】二分查找算法(下)

【算法】【优选算法】二分查找算法(下)

目录

一、852.⼭脉数组的峰顶索引

题目链接:852.⼭脉数组的峰顶索引
题目描述:

题目解析:

  • 给我们一个数组,元素是先递增在递减的,让我们返回最大元素下标。

1.1 二分查找

解题思路:

  • 我们这个数组本来就是一个被天然分成两段,递增区间和递减区间,的数据,天然使用二分查找的题。
  • 当mid的元素小于后一个元素的时候,mid在递增区间,所以left = mid + 1。
  • 当mid的元素大于后一个元素的时候,mid在递减区间,所以right = mid。

解题代码:

//时间复杂度:O(logN)//空间复杂度:O(1)classSolution{publicintpeakIndexInMountainArray(int[] arr){int left =0;int right = arr.length-1;while(left < right){int mid = left +(right - left)/2;if(arr[mid]< arr[mid+1]) left = mid +1;else right = mid;}return left;}}

1.2 暴力枚举

解题思路:

  • 直接使用for循环遍历数组,该下标元素大于前面和后面元素,返回下标。
  • 因为这个数组一定是一个山脉数组,所以不用管数组头和尾。

解题代码:

//时间复杂度:O(n)//空间复杂度:O(1)classSolution{publicintpeakIndexInMountainArray(int[] arr){for(int i =1; i < arr.length -1; i++){if(arr[i]> arr[i-1]&& arr[i]> arr[i+1])return i;}return0;}}

二、162.寻找峰值

题目链接:162.寻找峰值
题目描述;

题目解析:

  • 给我们的数组是,递增递减反复进行,让我们找到其中一个峰值的下标。
  • 数组可能是这几个情况:1 . /\/\/\ ,2. / ,3. \

2.1 二分查找

解题思路:

  • 其实我们可以将数组分为,有要求峰值和没有要求峰值两段,因为给了峰值不等于下一个元素。
  • 所以当mid小于下一个元素的时候,mid就是在没有要求峰值那段,left = mid+1。
  • 当mid大于下一个元素的时候,mid就是在有峰值那段,right = mid

解题代码:

//时间复杂度:O(logN)//空间复杂度:O(1)classSolution{publicintfindPeakElement(int[] nums){int left =0;int right = nums.length -1;while(left < right){int mid = left +(right - left)/2;if(nums[mid]< nums[mid +1]) left = mid +1;else right = mid;}return left;}}

2.2 暴力枚举

解题思路:

  • 直接转变为求数组最大值下标,遍历数组即可。

解题代码:

//时间复杂度:O(n)//空间复杂度:O(1)classSolution{publicintfindPeakElement(int[] nums){int ret =0;for(int i =0; i < nums.length; i++){if(nums[i]> nums[ret]) ret = i;}return ret;}}

三、153.寻找旋转排序数组中的最⼩值

题目链接:153.寻找旋转排序数组中的最⼩值
题目描述:

题目解析:

  • 数组旋转一次就代表将数组尾元素放在数组头。
  • 给我们一个原来升序的数组,旋转多次后,找到数组中最小元素下标。
  • 数组中元素各不相同。

数组会是下面这种状态或者一个完全递增的状态

3.1 二分查找

解题思路:

  • 我们这个数组本来就是已经是被分成两段了的。
  • 我们可以使用nums[ 0 ]或者nums[ nums.length - 1 ]来当分界线。
  • 使用nums[ nums.length - 1 ]为界限:
    • mid元素大于等于界限时,在数组段1,所以left = mid + 1。
    • mid元素小于界限的时候,在数组段2,所以right = mid。
  • 使用nums[ 0 ]为界限:
    • mid元素大于等于界限时,在数组段1,所以left = mid + 1。
    • mid元素小于界限的时候,在数组段2,所以right = mid。
    • 考虑数组完全递增时,nums[0]才是最小值。

解题代码:

//时间复杂度:O(logN)//空间复杂度:O(1)//使用nums[ nums.length - 1 ]为界限:classSolution{publicintfindMin(int[] nums){int left =0;int right = nums.length -1;while(left < right){int mid = left +(right - left)/2;if(nums[mid]< nums[nums.length-1]) right = mid;else left = mid +1;}return nums[left];}}//使用nums[ 0 ]为界限:classSolution{publicintfindMin(int[] nums){int left =0;int right = nums.length -1;while(left < right){int mid = left +(right - left)/2;if(nums[mid]>= nums[0]) left = mid +1;else right = mid;}if(nums[0]< nums[left]) left =0;return nums[left];}}

3.2 暴力枚举

解题思路;

  • 直接循环遍历数组找最小值即可。

解题代码:

//时间复杂度:O(n)//空间复杂度:O(1)classSolution{publicintfindMin(int[] nums){int ret = nums[0];for(int i =0; i < nums.length; i++){if(nums[i]< ret) ret = nums[i];}return ret;}}

四、LCR 173.点名

题目链接:LCR 173.点名
题目描述:

题目解析:

  • 给你一个长度为n数组,这个数组中有0到n中的数,按升序排列,找出数组在0到n中不含有的数。

4.1 二分查找

解题思路:

  • 这个数组分为这样两段,一段是下标与元素值相同的,一段是下标是元素值减1。
  • 所以当mid元素等于mid的时候,落在第一段,left = mid + 1;
  • 当mid元素不等于mid的时候,落在第二段,right = mid。

解题代码:

//时间复杂度:O(logN)//空间复杂度:O(1)classSolution{publicinttakeAttendance(int[] records){int left =0;int right = records.length;while(left < right){int mid = left +(right - left)/2;if(records[mid]== mid) left = mid +1;else right = mid;}return left;}}

4.2 哈希表

解题思路:

  • 借助一个数组来标记0到n中出现过的元素。

解题代码:

//时间复杂度:O(n)//空间复杂度:O(n)classSolution{publicinttakeAttendance(int[] records){int[] hash =newint[records.length +1];for(int i =0; i < records.length; i++){ hash[records[i]]++;}for(int i =0; i < hash.length; i++){if(hash[i]==0)return i;}return0;}}

4.3 暴力枚举

解题思路:

  • 直接遍历数组,当出现第一个下标和元素不相等的直接返回元素减一即可。
  • 遍历完数组还是没找到,证明是0到n中n不在数组中。

解题代码:

//时间复杂度:O(n)//空间复杂度:O(1)classSolution{publicinttakeAttendance(int[] records){for(int i =0; i < records.length; i++){if(records[i]!= i)return records[i]-1;}return records.length;}}

4.4 位运算

解题思路:

  • 直接使用一个变量来将0到n的数全部异或。
  • 在于数组元素进行异或。

解题代码:

//时间复杂度:O(n)//空间复杂度:O(1)classSolution{publicinttakeAttendance(int[] records){for(int i =0; i < records.length; i++){if(records[i]!= i)return records[i]-1;}return records.length;}}

4.5 数学(求和)

解题思路:

  • 直接先将0到n的和求出来。
  • 在减去数组中的元素即可。

解题代码:

//时间复杂度:O(n)//空间复杂度:O(1)classSolution{publicinttakeAttendance(int[] records){int n = records.length;int ret =(n*(n+1))/2;for(int i =0; i < records.length; i++){ ret = ret - records[i];}return ret;}}

Read more

2025浏览器指纹伪装终极指南:Playwright修改WebGL+时区+分辨率,小红书爬1000条零验证

2025浏览器指纹伪装终极指南:Playwright修改WebGL+时区+分辨率,小红书爬1000条零验证

2025年小红书反爬再升级,核心拦截逻辑已从“IP+UA”转向“浏览器指纹+行为特征”的双重校验——之前用普通Playwright爬虫爬500条笔记就触发滑块验证,换了3个代理池都没用;直到彻底搞定浏览器指纹伪装(WebGL+Canvas+时区+分辨率全维度对齐真实设备),再配合人类级行为模拟,爬1000条笔记零验证,IP存活时间从20分钟延长到8小时,数据准确率99.7%。 这篇文章不搞虚的,全程还原我2025年爬取小红书的实战经验:从小红书指纹检测的核心维度,到Playwright底层指纹修改的具体代码,再到零验证爬取的完整流程,每个步骤都附可直接运行的代码和验证方法,连“指纹一致性校验”“行为时序异常”这些新坑都给你填好,新手也能复现“1000条零验证”的效果。 一、先搞懂:2025小红书反爬的核心——浏览器指纹检测 小红书的反爬系统像个“设备安检员”,通过提取浏览器底层特征生成唯一“设备ID”,一旦识别到“机器指纹”,直接触发滑块/短信验证。2025年重点检测这5个指纹维度,缺一不可: 指纹类型检测核心爬虫常见暴露点WebGL指纹显卡厂商、渲染器型号、着色器参数P

By Ne0inhk
Java Web从入门到精通:全面探索与实战(二)

Java Web从入门到精通:全面探索与实战(二)

Java Web从入门到精通:全面探索与实战(一)-ZEEKLOG博客    目录 四、Java Web 开发中的数据库操作:以 MySQL 为例 4.1 MySQL 数据库基础操作 4.2 JDBC 技术深度解析 4.3 数据库连接池的应用 五、Java Web 中的会话技术:Cookie 与 Session 5.1 Cookie 详解 5.2 Session 详解 四、Java Web 开发中的数据库操作:以 MySQL 为例 4.1 MySQL 数据库基础操作

By Ne0inhk
【征文计划】玩转 Rokid JSAR:基于 Web 技术栈的 AR 开发环境搭建、核心 API 应用与 3D 时钟等创意项目全流程解析

【征文计划】玩转 Rokid JSAR:基于 Web 技术栈的 AR 开发环境搭建、核心 API 应用与 3D 时钟等创意项目全流程解析

【征文计划】玩转 Rokid JSAR:基于 Web 技术栈的 AR 开发环境搭建、核心 API 应用与 3D 时钟等创意项目全流程解析 前言 随着 AR 技术在消费级场景的普及,开发者对 “低门槛、高兼容” AR 开发工具需求愈发迫切,传统 AR 开发往往依赖专属引擎或复杂语法,导致 Web 开发者难以快速切入,而 Rokid 推出的 JSAR 技术,恰好打破了这一壁垒:以 “可嵌入空间的 Web 运行时” 为核心,让开发者无需学习新的开发范式,仅用 JavaScript/TypeScript 等熟悉的 Web 技术栈,就能快速开发出支持 3D 物体、

By Ne0inhk

从Web到全平台:Capacitor打包工具实战指南

作为前端开发者,你是否曾面临这样的困境:好不容易用React、Vue或Angular开发完Web应用,却被要求适配iOS和Android端?学习原生开发成本太高,找原生团队协作又耗时费力。今天要给大家介绍的Capacitor,正是解决这个痛点的利器——由Ionic团队打造的现代跨平台打包工具,能让Web开发者零原生基础也能构建全平台应用。 一、为什么选Capacitor?先看它的核心优势 在接触具体用法前,我们得先搞清楚:Capacitor凭什么成为Web转原生的优选?对比传统方案,它的优势太明显了: 1. 零框架侵入,适配所有Web项目 不同于某些强绑定框架的工具,Capacitor对前端技术栈完全无要求。不管你是用React写的管理系统、Vue开发的移动端页面,还是原生HTML/CSS/JS写的项目,都能直接接入打包。我曾把一个基于Vue3的官网快速打包成APP,整个过程没改一行业务代码。 2. 现代WebView加持,性能接近原生 Capacitor在iOS端采用WKWebView,Android端使用Chromium WebView,这俩都是各平台性能最优的Web

By Ne0inhk