LeetCode 每周算法 7(二分查找)

LeetCode 每周算法 7(二分查找)

二分查找算法:

在这里插入图片描述

class Solution {  
public:  // 定义一个函数,接收一个整数向量nums和一个整数target,返回目标值在数组中的插入位置  int searchInsert(vector<int>& nums, int target) {  int left = 0, right = nums.size() - 1; // 定义二分查找的左右边界// 当左边界小于等于右边界时,执行循环  while (left <= right) {  // 计算中间位置(注意:这里使用的是整数除法,结果向下取整)  int mid = (left + right) / 2;  // 如果中间位置的元素小于目标值,说明目标值在右半部分或就是右边界的值  if (nums[mid] < target) {  left = mid + 1; // 更新左边界为中间位置的下一个位置  } else {  // 如果中间位置的元素大于等于目标值,说明目标值在左半部分或就是当前中间位置的值  // 注意:这里用right = mid - 1是为了确保如果target是nums中的一个元素时,能返回它的正确索引  // 如果是要找插入位置,且target不在nums中,则应该直接返回left(因为此时left指向了第一个大于target的位置)  right = mid - 1; // 更新右边界为中间位置的前一个位置  }  }  // 当循环结束时,left将指向第一个大于target的位置(如果target不在nums中)  // 或者指向target在nums中的位置(如果target在nums中,并且前面有与其相等的元素)  // 由于题目要求返回插入位置,且数组已排序,因此直接返回left即可  return left;  }  
};

在这里插入图片描述

class Solution {  
public:  // 定义一个函数,接收一个二维整数向量matrix和一个整数target,返回是否在matrix中找到target  bool searchMatrix(vector<vector<int>>& matrix, int target) {  int m = matrix.size();       // 获取矩阵的行数  int n = matrix[0].size();    // 获取矩阵的列数(假设所有行长度相同)  int left = 0, right = m * n - 1; // 初始化二分查找的上下界,将整个矩阵视为一个一维数组进行查找  // 当left小于等于right时,执行循环  while (left <= right) {  // 计算中间位置(注意这里使用(right - left) / 2 + left来避免直接(left + right) / 2可能导致的溢出)  int mid = (left + right) / 2;  // 将一维的mid索引转换回二维的(x, y)索引  int x = mid / n;         // x是行索引  int y = mid % n;         // y是列索引   // 根据中间位置的值与目标值的比较结果,调整二分查找的上下界  if (matrix[x][y] < target) {  left = mid + 1; // 如果中间值小于目标值,则目标值在右半部分  } else if (matrix[x][y] > target) {  right = mid - 1; // 如果中间值大于目标值,则目标值在左半部分  } else {  return true; // 如果中间值等于目标值,则找到目标,返回true  }  }  // 如果循环结束还没有找到目标值,则返回false  return false;  }  
};

在这里插入图片描述

class Solution {  
public:  // 辅助函数:使用二分查找找到第一个大于或等于target//(当lower为true时)或第一个大于target(当lower为false时)的元素的索引  int binarySearch(vector<int>& nums, int target, bool lower) {  int left = 0, right = (int)nums.size() - 1, ans = (int)nums.size(); // 初始化左右边界和答案变量  while (left <= right) { // 当左边界小于等于右边界时继续搜索  int mid = (left + right) / 2; // 计算中间位置  if (nums[mid] > target || (lower && nums[mid] == target)) {  // 如果当前中间元素大于target,或者(lower为true且中间元素大于等于target)  // 则调整右边界,并将ans更新为mid(因为我们要找的是第一个满足条件的元素)  right = mid - 1;  ans = mid;  } else {  // 否则,继续向右搜索  left = mid + 1;  }  }  // 循环结束时,ans中存储的是第一个满足条件的元素的索引,或者如果都不满足,则为nums.size()  return ans;  }  // 主函数:查找target在nums中的范围(起始和结束索引),如果不存在则返回{-1, -1}  vector<int> searchRange(vector<int>& nums, int target) {  // 首先,通过binarySearch找到第一个大于等于target的元素的索引  int leftIdx = binarySearch(nums, target, true);  // 然后,通过binarySearch找到第一个大于target的元素的索引,并减1得到最后一个等于target的元素的索引  int rightIdx = binarySearch(nums, target, false) - 1;  // 检查找到的左右索引是否有效(即存在且target确实存在于该范围内)  if (leftIdx <= rightIdx && rightIdx < nums.size() && nums[leftIdx] == target && nums[rightIdx] == target) {  // 如果有效,则返回这个范围  return vector<int>{leftIdx, rightIdx};  }  // 否则,返回{-1, -1}表示未找到  return vector<int>{-1, -1};  }  
};

在这里插入图片描述

class Solution {  
public:  int search(vector<int>& nums, int target) {  int n = (int)nums.size(); // 获取数组nums的长度  if (!n) { return -1; } // 如果数组为空,则直接返回-1,表示未找到目标值  if (n == 1) { return nums[0] == target ? 0 : -1; } // 如果数组只有一个元素,则判断该元素是否为目标值,并返回相应结果  int l = 0, r = n - 1; // 初始化左右指针,分别指向数组的首尾  while (l <= r) { // 当左指针小于等于右指针时,进行循环  int mid = (l + r) / 2; // 计算中间位置索引  if (nums[mid] == target) return mid; // 如果中间位置的值等于目标值,则返回该位置索引  // 以下处理旋转数组的情况  if (nums[0] <= nums[mid]) { // 如果左半部分(包括mid)是有序的  if (nums[0] <= target && target < nums[mid]) { // 如果目标值在左半部分内  r = mid - 1; // 调整右指针,继续在左半部分搜索  } else {  l = mid + 1; // 否则,目标值在右半部分,调整左指针  }  } else { // 如果右半部分(不包括mid,但包括nums[0])是有序的  if (nums[mid] < target && target <= nums[n - 1]) { // 如果目标值在右半部分内  l = mid + 1; // 调整左指针,继续在右半部分搜索  } else {  r = mid - 1; // 否则,目标值在左半部分,调整右指针  }  }  }  return -1; // 如果循环结束仍未找到目标值,则返回-1  }  
};

在这里插入图片描述

class Solution {  
public:  int findMin(vector<int>& nums) {  // 定义左右指针,初始时分别指向数组的第一个和最后一个元素  int left = 0;  int right = nums.size() - 1;  // 当左指针小于右指针时,进行循环,确保能找到最小值  while (left < right) {  // 防止溢出,计算中点时使用 left + (right - left) / 2  int mid = left + (right - left) / 2;  // 如果中点元素小于右指针指向的元素,说明最小值在中点左侧(包括中点)  // 因为右半部分(mid+1到right)是有序的,且都大于nums[mid]  if (nums[mid] < nums[right]) {  right = mid;  }  // 如果中点元素大于等于右指针指向的元素,说明最小值在中点右侧  // 因为左半部分(left到mid)是无序的,但nums[mid]一定大于nums[left],  // 所以最小值不可能在左半部分,只能在中点右侧  else {  left = mid + 1;  }  }  // 当left == right时,循环结束,此时left(或right)指向的就是最小值的位置  // 返回该位置上的元素即为所求的最小值  return nums[left];  }  
};

在这里插入图片描述

class Solution {  
public:  // 查找两个有序数组中第k小的元素  int getKthElement(const vector<int>& nums1, const vector<int>& nums2, int k) {  int m = nums1.size(); // 数组nums1的长度  int n = nums2.size(); // 数组nums2的长度  int index1 = 0, index2 = 0; // 两个数组的起始索引  while (true) {  // 如果nums1已经遍历完,那么第k小的元素一定在nums2中  if (index1 == m) {  return nums2[index2 + k - 1];  }  // 如果nums2已经遍历完,那么第k小的元素一定在nums1中  if (index2 == n) {  return nums1[index1 + k - 1];  }  // 如果k为1,那么当前两个指针指向的元素中较小的那个就是第k小的元素  if (k == 1) {  return min(nums1[index1], nums2[index2]);  }  // 在两个数组中分别找到第k/2小的元素的索引,但不超过数组长度  int newIndex1 = min(index1 + k / 2 - 1, m - 1);  int newIndex2 = min(index2 + k / 2 - 1, n - 1);  int pivot1 = nums1[newIndex1]; // nums1中的第k/2小的元素  int pivot2 = nums2[newIndex2]; // nums2中的第k/2小的元素  // 根据pivot1和pivot2的大小关系,决定排除哪一部分的元素  if (pivot1 <= pivot2) {  // 如果nums1的第k/2小的元素小于等于nums2的第k/2小的元素  // 那么nums1中前newIndex1+1个元素都不可能是第k小的元素  k -= newIndex1 - index1 + 1;  index1 = newIndex1 + 1;  } else {  // 如果nums1的第k/2小的元素大于nums2的第k/2小的元素  // 那么nums2中前newIndex2+1个元素都不可能是第k小的元素  k -= newIndex2 - index2 + 1;  index2 = newIndex2 + 1;  }  }  }  // 查找两个有序数组的中位数  double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {  int totalLength = nums1.size() + nums2.size(); // 两个数组的总长度  if (totalLength % 2 == 1) {  // 如果总长度为奇数,则中位数为第(totalLength+1)/2小的元素  return getKthElement(nums1, nums2, (totalLength + 1) / 2);  } else {  // 如果总长度为偶数,则中位数为第(totalLength/2)小和第(totalLength/2+1)小元素的平均值  return (getKthElement(nums1, nums2, (totalLength + 1) / 2) + getKthElement(nums1, nums2, totalLength / 2 + 1)) / 2.0;  }  }  
};

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

golang学习笔记4-基本数据类型

声明&#xff1a;本人已有C&#xff0c;C,Python基础&#xff0c;只写本人认为的重点&#xff0c;方便自己回顾。 go的数据类型如下 由于bool和c类似&#xff0c;和go的区别是&#xff0c;bool的值只能取true和false&#xff0c;不能取整数&#xff0c;而且有默认值false。 一…

让C#程序在linux环境运行

今晚花一些时间&#xff0c;总结net程序如何在linux环境运行的一些技术路线。 1、采用.Net Core框架 NET Core 使用了 .NET Core Runtime&#xff0c;它可以在 Windows、Linux 和 macOS 等多个操作系统上运行。可以采用Visual Studio生成Linux版本的dll。 在Linux系统中&…

系统架构笔记-2-计算机系统基础知识

知识要点-2.6计算机语言 UML 对系统架构的定义是系统的组织结构&#xff0c;包括系统分解的组成部分以及它们的关联性、交互机制和指导原则等&#xff0c;提供系统设计的信息。 具体有以下 5 个系统视图&#xff1a; 1. 逻辑视图&#xff1a;也称为设计视图&#xff0c;表示…

【WEB】EZ_Host

1、 2、解答 http://8762a9b0-5aa3-49f8-b8d2-54e4cb0746cc.www.polarctf.com:8090/?hostlocalhost;lshttp://8762a9b0-5aa3-49f8-b8d2-54e4cb0746cc.www.polarctf.com:8090/?hostlocalhost;cat flag即可看到答案

【亿美软通-注册/登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

14.面试算法-字符串常见算法题(三)

1. 字符串回文问题 1.1 LeetCode.125. 验证回文串 回文问题在链表中是重点&#xff0c;在字符串中同样是个重点。当初我去美团面试第一轮技术面的第一个算法题就是让写判断字符串回文的问题。 这个本身还是比较简单的&#xff0c;只要先转换成字符数组&#xff0c;然后使用双…

OctoSQL 查询大量数据库和文件格式

OctoSQL 主要是一款 CLI 工具&#xff0c;可让你通过统一界面使用 SQL 查询大量数据库和文件格式&#xff0c;甚至在它们之间进行连接。同时&#xff0c;它还是一个易于扩展的完整数据流引擎&#xff0c;你可以用它为自己的应用程序添加 SQL 接口 OctoSQL是一款功能强大的SQL查…

Git从了解到操作

Git常用命令 基本的linux命令 ls / ll 查看当前目录( ls 是查看目录有哪些文件夹&#xff0c;ll 是查看隐藏文件)cat 查看文件内容touch 创建文件vi vi编辑器 (使用 vi 编辑器是为了方便展示效果&#xff0c;也可以记事本、editPlus、notPad等其它编辑器) 备注 Git GUl: Gi…

docker基本(仅供自己参考)

一、大型项目部署的问题&#xff1a; 1、大型项目的组件比较多&#xff0c;运行环境很复杂&#xff0c;部署通常会遇到各种问题&#xff1a; &#xff08;1&#xff09;&#xff1a;依赖关系复杂&#xff0c;容易出现兼容性问题 &#xff08;2&#xff09;&#xff1a;开发、…

雪花算法Snowflake

雪花算法常用于分布式的项目中&#xff0c;是为了解决大数据产生的多表分表中&#xff0c;保证id的唯一性。 1.分布式的特点 全局唯一性&#xff1a;不能出现有重复ID的标识&#xff1b;地增性&#xff1a;确保生成的ID对用于用户或业务是递增的&#xff1b;高可用性&#xf…

施耐德EcoStruxure Machine SCADA Expert(EMSE)与SQL数据库连接(十五)

我习惯使用SQL Server 数据库与EMSE进行连接。 用的是sql 2017 关于数据库软件的安装教程 网上一大把。 1.新建数据库 打开数据库管理工具&#xff0c;新建数据库 2.新建表单 &#xff08;ps:这里先做一个小测试-----目的是验证与EMSE软件的链接是否顺畅。) 添加两个元素进去…

flask的学习记录

结构如下&#xff1a; app.py from App import create_appapp create_app()if __name__ __main__:app.run(debugTrue,host0.0.0.0,port5000) App/__init__.py from flask import Flask, render_template, request, redirect, url_for from .views import blue from .exts …

VisualPromptGFSS

COCO-20 i ^i i太大&#xff0c;不建议复现

golang学习笔记1-go程序执行流程

声明&#xff1a;本人已有C&#xff0c;C,Python基础&#xff0c;只写本人认为的重点&#xff0c;方便自己回顾。 命令行执行go程序有两种方式&#xff0c;其流程如下图 注意第一种方式会得到可执行文件&#xff0c;第二种不会。 例1 在当前目录下编译hello.go go build hel…

TypeScript入门 (三)数据类型

引言 大家好&#xff0c;我是GISer Liu&#x1f601;&#xff0c;一名热爱AI技术的GIS开发者。本系列文章是我跟随DataWhale 2024年9月学习赛的TypeScript学习总结文档。本文旨在全面介绍 TypeScript 中的各种数据类型&#xff0c;帮助读者深入理解每种数据类型的用法、内置属性…

Matlab simulink建模与仿真 第十九章(生成C代码)

一、Configuration Parameters模型参数配置 1、仿真时间 &#xff08;1&#xff09;在Solver选项卡中可以设置仿真的起始时间和结束时间&#xff0c;一般起始时间设为0&#xff0c;而结束时间按需设置。 &#xff08;2&#xff09;如果希望仿真不会自动暂停&#xff08;也就…

Qwen大型语言模型系列的最新成果 ----Qwen2.5

通义千问2.5-7B-Instruct-GGUF 模型库 (modelscope.cn) apt install git-lfsgit lfs installgit clone https://www.modelscope.cn/qwen/Qwen2.5-7B-Instruct-GGUF.git

(done) 声音信号处理基础知识(3) (一个TODO: modulation 和 timbre 的关联)(强度、响度、音色)

来源&#xff1a;https://www.youtube.com/watch?vJkoysm1fHUw sound power 通常可以被认为是能量传输的速率 声源往所有方向传输的每时间单位能量 用 瓦特(W) 作为单位测量 Sound intensity 声音强度&#xff0c;每单位面积的 sound power W/m^2 人类实际上能听到非常小强…

Mybatis+Druid+MybatisPlus多数据源配置

MybatisDruidMybatisPlus多数据源配置 平常我们使用的是 properties 或者 yaml 来配置数据库的地址、用户名、密码等 但是这样只能配置一个数据源 现在我们想在一个项目里面配置多个数据源&#xff0c;那么我们就需要配置自己的配置类 配置类和配置文件 Mybatismysqldruid配置…

此框架你到底了解多少???

1.简述对Spring中IOC/DI的理解 IOC&#xff1a;控制反转&#xff0c;将创建和管理的对象的任务交给外部的Spring容器 DI&#xff1a;依赖注入&#xff0c;对象之间存在依赖关系&#xff0c;创建对象时&#xff0c;对其依赖的对应直接进行赋值 2.有哪些依赖注入的方式 基于注…