一个月速刷leetcodeHOT100 day14 彻底搞懂二分搜索 以及相关题目

二分查找算法(Binary Search Algorithm)

是一种用于在已排序数组中查找特定元素的高效算法。它的基本思想是每次将待查找的区间分成两部分,并确定目标元素位于哪一部分中,然后只在目标区间中继续查找,直到找到目标元素或者确定目标元素不存在。

基本实现

function BinarySearch(nums, target) {

let [left, right] = [0, nums.length - 1];

while (left <= right) {

let mid = left + Math.floor((right - left) / 2);

if (target === nums[mid]) {

return mid;

} else if (target > nums[mid]) {

left = mid + 1;

} else {

right = mid - 1;

}

}

return -1;

}

二、寻找左/右侧边界的二分搜索

一个数组[1,2,2,2,3,4]查找2

function left_bound(nums,target) {

let [left, right] = [0, nums.length - 1];

// 搜索区间为 [left, right]

while (left <= right) {

let mid = left + (right - left) / 2;

if (nums[mid] < target) {

// 搜索区间变为 [mid+1, right]

left = mid + 1;

} else if (nums[mid] > target) {

// 搜索区间变为 [left, mid-1]

right = mid - 1;

} else if (nums[mid] === target) {

// 收缩右侧边界

right = mid - 1;
// 收缩左侧边界
//left = mid + 1
}

}

return left;

}

搜索插入位置

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
示例 1:
输入: nums = [1,3,5,6], target = 5
输出: 2
示例 2:
输入: nums = [1,3,5,6], target = 2
输出: 1
示例 3:
输入: nums = [1,3,5,6], target = 7
输出: 4

var searchInsert = function(nums, target) {
j j
if(nums.length==1) return nums[0]>=target?0:1;

let start=0, end =nums.length;

if(target<=nums[0]) return 0;

let mid = 0;

while(start<=end) {

mid=parseInt((start+end)/2);

if(nums[mid]==target) return mid;

else if(nums[mid]>target) {

end = mid-1;

if(target>nums[end]) return mid;

}else {

start = mid+1;

if(target<=nums[start]) return start;

}

}

return nums.length;

};

搜索二维矩阵

给你一个满足下述两条属性的 m x n 整数矩阵:

  • 每行中的整数从左到右按非严格递增顺序排列。
  • 每行的第一个整数大于前一行的最后一个整数。

给你一个整数 target ,如果 target 在矩阵中,返回 true ;否则,返回 false 。

示例 1:

**输入:**matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
**输出:**true

示例 2:

**输入:**matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 13
**输出:**false

var searchMatrix = function(matrix, target) {

let m = matrix.length;

let n = matrix[0].length;

let low = 0;

let high = m*n-1;

while(low <= high) {
//  `>>` 是 JavaScript 中的位右移运算符,它将一个数字的二进制表示向右移动指定的位数。在这个上下文中,`high - low` 表示了索引范围的大小,将其右移一位,相当于将范围大小除以2。
//let mid = low + (hight -low) / 2 
let mid = low +((high - low) >> 1);
//一维索引 `mid` 除以列数 `n`,得到的结果表示 `mid` 所在的行数
//用得到的行索引和列索引来访问二维矩阵中的特定元素
let value = matrix[Math.floor(mid/n)][mid%n]


if( value < target){

low = mid + 1;

} else if(value > target) {

high = mid -1;

}

else {

return true;

}

}

return false;

};

在排序数组中查找元素的第一个和最后一个位置

给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。

如果数组中不存在目标值 target,返回 [-1, -1]

你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。

示例 1:

**输入:**nums = [5,7,7,8,8,10], target = 8
输出:[3,4]

示例 2:

**输入:**nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]

示例 3:

**输入:**nums = [], target = 0
输出:[-1,-1]
思路:两次while循环 寻找左边界和右边界或找到值后左右查找

var searchRange = function(nums, target) {
  let result = [-1, -1];
  let len = nums.length;
  if (len === 0) return result;
	// 寻找左边界 
  let l = 0, r = len - 1;
  while (l < r) {
  
    let mid = (l + r) / 2 | 0;
    
    if (target <= nums[mid]) r = mid;
    else l = mid + 1
    
  }
  if (nums[l] !== target) return result;
  result[0] = l;

  r = len - 1;
  while(l < r) {
    let mid = (l + r) / 2 | 0;
    if (target >= nums[mid]) l = mid + 1
    else r = mid;
  }
  if (nums[r] === target) result[1] = r
  else result[1] = r - 1
  return result;
};

//2.
var searchRange = function(nums, target) {
    let left = 0, right = nums.length - 1, mid;
    while (left <= right) {
        mid = (left + right) >> 1;
        if (nums[mid] === target) break;
        if (nums[mid] > target) right = mid - 1;
        else left = mid + 1;
    }
    if(left > right) return [-1, -1];

搜索旋转排序数组

整数数组 nums 按升序排列,数组中的值 互不相同 。

在传递给函数之前,nums 在预先未知的某个下标 k0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经K旋转后可能变为 [4,5,6,7,0,1,2] 。

给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。

你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。

示例 1:

**输入:**nums = [4,5,6,7,0,1,2], target = 0
**输出:**4

示例 2:

**输入:**nums = [4,5,6,7,0,1,2], target = 3
输出:-1

示例 3:

**输入:**nums = [1], target = 0
输出:-1
这最简单的办法直接indexOf就行 可这是二分查找的题

var search = function(nums, target) {
return nums.indexOf(target)
};
var serch = function(nums,target){
let left = 0
  let right = nums.length - 1
  while(left <= right) {
    let mid = (left + right) >> 1
     
	    if(nums[mid] == target) return mid
 // 如果中间数小于最右边数,则右半段是有序的
        // 如果中间数大于最右边数,则左半段是有序的
    if(nums[mid] < nums[right]) {
      if(target <= nums[right] && target > nums[mid]) {
      
//如果在,则中间数右移left
        left = mid + 1
      } else {
        right = mid - 1
      }
    } else {
      if(target < nums[mid] && target >= nums[left]) {
        right = mid - 1
      } else {
        left = mid + 1
      }
    }

  }
  return -1
}

}

寻找旋转排序数组中的最小值

已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到:

  • 若旋转 4 次,则可以得到 [4,5,6,7,0,1,2]
  • 若旋转 7 次,则可以得到 [0,1,2,4,5,6,7]

注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]] 。

给你一个元素值 互不相同 的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。

你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。

示例 1:

**输入:**nums = [3,4,5,1,2]
**输出:**1
**解释:**原数组为 [1,2,3,4,5] ,旋转 3 次得到输入数组。

示例 2:

**输入:**nums = [4,5,6,7,0,1,2]
**输出:**0
**解释:**原数组为 [0,1,2,4,5,6,7] ,旋转 3 次得到输入数组。

示例 3:

**输入:**nums = [11,13,15,17]
**输出:**11
**解释:**原数组为 [11,13,15,17] ,旋转 4 次得到输入数组。

思路:简单做法排序后直接shift,如果通过二分法, 判断 nums[mid] 与 nums[right] 的大小关系: 如果 nums[mid] > nums[right],说明最小元素在 mid 的右侧,因此更新 left = mid + 1。 否则,最小元素在 mid 或者 mid 的左侧,因此更新 right = mid。 当 left 和 right 相遇时,循环结束,此时 left 指向的位置就是最小元素的位置。
var findMin = function(nums) {
return nums.sort((a,b)=>a-b).shift()
};
var findMin = function (nums) {
let [left,right]= [0,nums.length -1]

while (left < right) {

const mid = (right + left) >> 1

if (nums[mid] > nums[right]) {

left = mid + 1

} else {

right = mid

}

}

return nums[left]

};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

水经微图IOS版5.3.0发布

随时随地&#xff0c;微图一下&#xff01; 水经微图&#xff08;以下简称“微图”&#xff09;IOS版&#xff0c;新版已上线。 当前版本 当前版本号为&#xff1a;5.3.0-beta 如果你发现该版本中存在问题&#xff0c;请及时反馈给我们修订。 关于我们产品的版本控制&…

国产工业级实时数据库

项目功能描述 Mars数据库的核心功能在于其能够高效地处理来自工业现场的大量传感器数据。它通过简化的可视化配置&#xff0c;允许用户轻松接入各种传感器&#xff0c;并进行数据记录和逻辑处理。Mars数据库在单机模式下支持高达120万个传感器信号的接入&#xff0c;而其分布式…

【文末附gpt升级秘笈】埃隆·马斯克芯片调配策略对特斯拉股价的影响分析

埃隆马斯克芯片调配策略对特斯拉股价的影响分析 一、引言 在现代商业环境中&#xff0c;企业间的资源调配与策略布局往往对其股价产生深远影响。据外媒CNBC报道&#xff0c;埃隆马斯克在芯片资源分配上的决策引起了业界的广泛关注。他秘密要求英伟达将原本预留给特斯拉的高端…

TMS320F280049学习3:烧录

TMS320F280049学习3&#xff1a;烧录 文章目录 TMS320F280049学习3&#xff1a;烧录前言一、烧录RAM二、烧录FLASH总结 前言 DSP的烧录分为两种&#xff0c;一种是将程序烧录到RAM中&#xff0c;一种是烧录到FLASH中&#xff0c;烧录ARM中的程序&#xff0c;只要未掉电&#x…

Vue3项目准备:utils工具插件文件夹中封装request.js配置axios请求基地址及超时时间、请求拦截器、响应拦截器

token介绍 概念&#xff1a;访问权限的令牌&#xff0c;本质上是一串字符串 创建&#xff1a;正确登录后&#xff0c;由后端签发并返回 作用&#xff1a;判断是否有登录状态等&#xff0c;控制访问权限 注意&#xff1a;前端只能判断token有无&#xff0c;而后端才能判断tok…

Camtasia Studio2024永久免费版及最新版本功能讲解

在当前数字化时代&#xff0c;视频内容的制作与编辑变得愈发重要。无论是企业宣传、在线教育还是个人Vlog制作&#xff0c;一款功能强大且易于上手的视频编辑软件成为了刚需。Camtasia Studio作为市场上备受欢迎的视频编辑与屏幕录像工具&#xff0c;凭借其强大的功能与用户友好…

在线标注流程

文章目录 在线标注流程标注方法 在线标注流程 登录地址&#xff1a;http://7a27c5e078f644a2a9b734603913c65e.login.bce.baidu.com 出现页面&#xff1a; 登录名&#xff1a; 三个中任意一个 密码&#xff1a;ZNSJ123a 登录之后叉掉。再打开这个网站&#xff1a;https://…

2938. 区分黑球与白球

题目 桌子上有 n 个球&#xff0c;每个球的颜色不是黑色&#xff0c;就是白色。 给你一个长度为 n 、下标从 0 开始的二进制字符串 s&#xff0c;其中 1 和 0 分别代表黑色和白色的球。 在每一步中&#xff0c;你可以选择两个相邻的球并交换它们。 返回「将所有黑色球都移到…

Leetcode:电话号码的字母组合

题目链接&#xff1a;17. 电话号码的字母组合 - 力扣&#xff08;LeetCode&#xff09; 普通版本&#xff08;回溯&#xff09; class Solution { public:string tmp;//临时存放尾插内容vector<string> res;//将尾插好的字符串成组尾插给resvector<string> board{…

⌈ 传知代码 ⌋ AI驱动食物图像识别

&#x1f49b;前情提要&#x1f49b; 本文是传知代码平台中的相关前沿知识与技术的分享~ 接下来我们即将进入一个全新的空间&#xff0c;对技术有一个全新的视角~ 本文所涉及所有资源均在传知代码平台可获取 以下的内容一定会让你对AI 赋能时代有一个颠覆性的认识哦&#x…

【数据结构】平衡二叉树(AVL树)

目录 前言 一、AVL树概念 二、AVL树节点定义 三、AVL树插入 1. 按照二叉搜索树的方式插入新节点 2. 维护节点的平衡因子与调整树的结构 a. 新节点插入较高左子树的左侧---左左&#xff1a;右单旋 b. 新节点插入较高右子树的右侧---右右&#xff1a;左单旋 c. 新节点插入…

前端面试项目细节重难点(已工作|做分享)想(八)

面试官&#xff1a;请你讲讲你在该项目中遇到的印象深刻的问题是什么&#xff1f; 答&#xff1a;我的回答&#xff1a;该项目的实现过程中我确实遇到了问题&#xff1a;【我会给大家整理回答思路和角度&#xff0c;那那么遇到这样的问题也可借鉴这种思路进行阐述】 第一层面…

RocketMQ教程(五):RocketMQ的工作原理2

工作原理 RocketMQ 是一个高性能、高吞吐量的分布式消息和流计算平台,它基于发布-订阅模式工作。其核心设计理念是确保消息传递的高效性、稳定性和可扩展性。RocketMQ 的工作原理主要可以分为以下几个部分: 1. 消息流程 消息发布: Producer 首先向 NameServer 查询目标 Top…

二重,三重积分和曲面,曲线积分的关系和区别

这是我在学习完曲面曲线积分概念后容易和二重三重积分混淆而大概总结和区分了一下&#xff0c;如果有错误请大佬指出&#xff0c;多谢&#xff01;&#xff01;&#xff01;

shell(一)

shell 既是脚本语言又是应用程序 查看自己linux系统的默认解析&#xff1a;echo $SHELL 创建第一个shell 文件 touch 01.sh编辑 vi 01.sh01.sh 文件内容 #!/bin/bash echo felicia保存 按Esc 然后输入:wq 定义以开头&#xff1a;#!/bin/bash #!用来声明脚本由什么shell解释…

无线麦克风什么牌子的音质效果好?一文揭秘领夹麦克风哪个品牌好

​近年来&#xff0c;无线领夹麦克风在各个领域都大放异彩&#xff0c;无论是直播、采访还是上课&#xff0c;都能看到它的身影。这款小小的无线麦克风&#xff0c;蕴含着巨大的能量&#xff0c;为媒体人的创作提供了强大的支持。对于想要更新设备的媒体人来说&#xff0c;现在…

打造国产软硬件一体化解决方案 YashanDB与宏杉科技完成多项兼容互认证

近日&#xff0c;深圳计算科学研究院崖山数据库系统YashanDB与宏杉科技系列存储、系列服务器与数据库一体机等多款产品顺利完成兼容性互认证。经严格测试&#xff0c;双方产品完全兼容&#xff0c;稳定运行&#xff0c;共同提供高效、稳定、安全的国产软硬件一体化解决方案&…

tmux工具使用鼠标滚动窗口及分屏命令

tmux工具使用鼠标滚动窗口及分屏命令 1. tmux source配置文件 长期生效2. 临时生效3. 实现分屏 1. tmux source配置文件 长期生效 vim ~/.tmux.conf echo "set -g mouse on" > ~/.tmux.conf tmux source-file ~/.tmux.conf2. 临时生效 1. 进入到tmux命令窗口 2.…

流水线建构apk、abb实战(一)

在构建机上需要下载的工具 流水线中的构建机无法使用Android Studio中自带的sdk工具下载&#xff0c;所以得下载commandlinetools命令行工具&#xff0c;下载后使用随附的 sdkmanager 下载其他 SDK 软件&#xff0c;解压后按照/cmdline-tools/latest/bin/sdkmanager目录结构整…

【Java毕业设计】基于Java的教师考勤管理系统的设计与实现

文章目录 摘 要ABSTRACT目 录1 概述1.1 研究背景及意义1.2 国内外研究现状1.3 拟研究内容1.4 系统开发技术1.4.1 vue技术1.4.2 B/S结构1.4.3 Spring Boot框架1.4.4 MySQL数据库1.4.5 MVC模式 2 系统需求分析2.1 可行性分析2.2 功能需求分析 3 系统设计3.1 功能结构设计3.2 系统…