算法训练 —— 数组(1)

news2024/11/17 23:45:44

目录

一、二分查找的基本原理

二、二分查找的基本写法

三、二分查找的相关例题 

1. LeetCode704.二分查找 

2. LeetCode35.搜索插入位置

3. LeetCode34.在排序数组中查找的第一个和最后一个位置

4. LeetCode69.x的平方根

5. LeetCode367.有效的完全平方数


一、二分查找的基本原理

        二分查找又称折半查找,意指将待查找的集合通过判定某种条件将该集合一分为二,即左区间和右区间,两个区间只有一个区间是满足该条件的,再次判定该条件,再次划分,直到区间划分完毕。下面看动图演示

二、二分查找的基本写法

写法一:

// 版本一
class Solution {
public:
    int binary_search(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size() - 1; // 定义target在左闭右闭的区间里,[left, right]
        while (left <= right) 
        { 
            int mid = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2
            if (nums[mid] > target) 
            {
                right = mid - 1; // target 在左区间,所以[left, mid - 1]
            } 
            else if (nums[mid] < target) 
            {
                left = mid + 1; // target 在右区间,所以[mid + 1, right]
            } 
            else // nums[mid] == target
            { 
                return mid; // 数组中找到目标值,直接返回下标
            }
        }
        
        return -1;// 未找到目标值
    }
};

写法二:

// 版本二
class Solution {
public:
    int binary_search(vector<int>& nums, int target) 
    {
        int left = 0;
        int right = nums.size(); // 定义target在左闭右开的区间里,即:[left, right)
        while (left < right) 
        { 
            int mid = left + ((right - left) >> 1);
            if (nums[mid] > target) 
            {
                right = mid; // target 在左区间,在[left, mid)中
            } 
            else if (nums[mid] < target) 
            {
                left = mid + 1; // target 在右区间,在[mid + 1, right)中
            } 
            else // nums[mid] == target
            { 
                return mid; // 数组中找到目标值,直接返回下标
            }
        }
        
        return -1;// 未找到目标值
    }
};

三、二分查找的相关例题 

1. LeetCode704.二分查找 

链接:二分查找 

题解:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size();
        while(left < right)
        {
            int mid = (left + right) / 2;
            if(nums[mid] > target)
            {
                right = mid;
            }
            else if(nums[mid] < target)
            {
                left = mid + 1;
            }
            else
            {
                return mid;
            }
        }
        return -1;
    }
};

2. LeetCode35.搜索插入位置

链接:搜索插入位置

题解:

对于第三次二分后,我们发现left、right和mid同时指向了数组中的最后一个元素;
这种情况只要是target不存在,一定会走到这一步。
此时又会分两种情况:

  1. 当target > nums[mid] 时:right = mid - 1,此时二分结束,right的下标是-1,left的下标是0;
  2. 当target < nums[mid] 时:left = mid + 1,此时二分结束,right的下标是0,left的下标是1;

我们一定是将target插入到right和left之间,如何插入正确的下标中:

  • 首先,left、right和mid是同一个下标;
  • left = mid + 1表明target比mid下标对应的值要大;left++的这个位置就是该target所在位置,或者right+1;因为right和left是连续的下标。
  • right = mid - 1表明target比mid下标对应的值要小;right + 1这个位置就是该target所在位置,或者left;因为right和left是连续的下。
  • 这两种情况,都是一样的,就合成一种情况了。
class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size() - 1;
        while(left <= right)
        {
            int mid = (left + right) / 2;
            if(nums[mid] < target)
            {
                left = mid + 1;
            }
            else if(nums[mid] > target)
            {
                right = mid - 1;
            }
            else
            {
                return mid;
            }
        }
        return left;//return right + 1;
    }
};

3. LeetCode34.在排序数组中查找的第一个和最后一个位置

链接:在排序数组中查找的第一个和最后一个位置

题解1:

寻找target在数组里的左右边界,有如下三种情况:

  • 情况一:target 在数组范围的右边或者左边,例如数组{3, 4, 5},target为2或者数组{3, 4, 5},target为6,此时应该返回{-1, -1}
  • 情况二:target 在数组范围中,且数组中不存在target,例如数组{3,6,7},target为5,此时应该返回{-1, -1}
  • 情况三:target 在数组范围中,且数组中存在target,例如数组{3,6,7},target为6,此时应该返回{1, 1}

如何找左右边界:

从图中给的例子来看,target=6 的区间是[4, 5],但是我们的leftBorder和rightBorder是[3,6],没关系,我们只需要在后续处理中将leftBorder+1和rightBorder-1即可;下面看代码:

class Solution {
private:
    int GetLeftBorder(vector<int>& nums, int target)
    {
        int left = 0;
        int right = nums.size() - 1;
        int leftBorder = -2;//定义左区间,这是用来判断有没有被赋值过
        //为什么给-2,因为right在向左区间移动时,最坏移动到下标 -1 的位置
        while(left <= right)
        {
            int mid = (left + right) / 2;
            if(nums[mid] >= target)//此时区间被划分为[left, mid - 1]
            {
                right = mid - 1;
                leftBorder = right;//有可能nums[mid] == target,记录target的左开区间
            }
            else//此时区间被划分为[mid + 1, right]
            {
                left = mid + 1;
            }
        }
        return leftBorder;
    }

    int GetRightBorder(vector<int>& nums, int target)
    {
        int left = 0;
        int right = nums.size() - 1;
        int rightBorder = -2;//定义左区间,这是用来判断有没有被赋值过
        while(left <= right)
        {
            int mid = (left + right) / 2;
            if(nums[mid] > target)//此时区间被划分为[left, mid - 1]
            {
                right = mid - 1; 
            }
            else//此时区间被划分为[mid + 1, right]
            {
                left = mid + 1;
                rightBorder = left;//有可能nums[mid] == target,记录target的右开区间
            }
        }
        return rightBorder;
    }
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        int leftBorder = GetLeftBorder(nums, target);
        int rightBorder = GetRightBorder(nums, target);
        //情况1:
        if(leftBorder == -2 || rightBorder == -2) return {-1, -1};
        //情况3:因为是两个记录的都是开区间,只要相减大于1,必然target存在于数组中,将leftBorder + 1和rightBorder - 1
        if(rightBorder - leftBorder > 1) return {leftBorder + 1, rightBorder - 1};
        //情况2:
        return {-1, -1};
    }
};

4. LeetCode69.x的平方根

链接: x的平方根

题解: 

class Solution {
public:
    int mySqrt(int x) {
        double left = 0;
        double right = x;
        while((right - left) > 1e-8)
        {
            double mid = (left + right) / 2;
            if(mid * mid >= x)
            {
                right = mid;
            }
            else
            {
                left = mid;
            }
        }
        return right;
    }
};

5. LeetCode367.有效的完全平方数

链接:有效的平方数

题解:这道题相对来说简单一些; 

class Solution {
public:
    bool isPerfectSquare(int num) {
        //如果num有完全平方数,那么完全平方数一定在0~num中
        int left = 0,right = num;
        while(left <= right)
        {
            int mid = (left + right) / 2;
            long square = (long)mid * mid;
            if(square < num)//表明mid < num,区间变为[mid + 1,right]
            {
                left = mid + 1;
            }
            else if(square > num)//表明mid > num,区间变为[left,mid + 1]
            {
                right = mid - 1;
            }
            else //square == num,表明mid就是要找的完全平方数
            {
                return true;
            }
        }
        return false;
    }
};

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

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

相关文章

华为手表开发:WATCH 3 Pro(2)生成密钥和证书请求文件,生成签名和配置签名

华为手表开发&#xff1a;WATCH 3 Pro&#xff08;2&#xff09;生成密钥和证书请求文件&#xff0c;生成签名和配置签名初环境与设备生成密钥生成签名初 希望能写一些简单的教程和案例分享给需要的人 环境与设备 系统&#xff1a;window 设备&#xff1a;HUAWEI WATCH 3 Pr…

12.28日报

今天主要进行了资产盘点工作&#xff1b; 写了一个数据库的增删改查的接口框架&#xff1b; 遇到的问题与解决&#xff1a; Insert没使用过&#xff0c;查阅资料&#xff0c;对其初步了解 postMan使用不熟练&#xff0c;搜索配置方法&#xff0c;多练习 网关服务 基本原理…

大话设计模型 Task06:桥接、职责链、中介

目录一、桥接模式问题描述问题分析模式定义代码实现二、职责链模式问题描述问题分析模式定义代码实现三、中介模式问题描述问题分析模式定义优缺点代码实现四、命令模式&#xff08;后补&#xff09;问题描述问题分析模式定义代码实现五、享元模式&#xff08;后补&#xff09;…

面向制造业的文档管理

面向制造业的文档管理 借助DocuWare领先的文档管理和工作流程自动化解决方案&#xff0c;各行业制造商&#xff08;从金属制造和机器零件到生物技术和制药&#xff09;都可以获得具有成本效益的可持续解决方案&#xff0c;通过自动化工作流程&#xff0c;简化生产和管理流程。…

文件压缩与远程拷贝_Tar_Scp_Rsync

Tar 压缩文件类型分为&#xff1a;gzip,bzip2,xz.利用tar工具来解压&#xff0c;压缩。 tar common:#tar [option ] file_name -c 创建一个压缩包 -t 查看内容 -x 提取 -f 文件名&#xff08;必须用&#xff09; -v 详细过程 -j bzip2 -z gzip -J xz Meth: tar -czvf arch_n…

示波器应用(一)

程序同学有没有一种感觉&#xff0c;有时候看到游戏场景有一种难以言表的不舒服&#xff0c;但是又不知道画面到底为什么不舒服。美术同学看到好的作品想要”借鉴“&#xff0c;但是又无从下手。那么下面这套工具将会非常适合进行画面分析以及画面仿色。让程序看懂画面信息&…

Ansys Speos | 进行智能手机镜头杂散光分析

本例的目的是研究智能手机Camera系统的杂散光。杂散光是指光向相机传感器不需要的散光光或镜面光&#xff0c;是在光学设计中无意产生的&#xff0c;会降低相机系统的光学性能。 在本例中&#xff0c;光学透镜系统使用Ansys Zemax OpticStudio (ZOS)进行设计&#xff0c;并使用…

微信小程序会议OA-后台数据交互(首页)05

1.后台准备 1.1 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache…

Charles -抓不到包常见原因之证书过期失效处理方法

当出现环境配置正常但却无法抓包的时候&#xff0c;可能是因为证书失效了&#xff0c;这种情况移除旧证书&#xff0c;安装新的证书即可。 一、判断是否证书过期 iOS手机&#xff1a; 进入&#xff1a;设置 > 通用 > VPN与设备管理 > Charles Proxy CA... > 更多…

劲爆美女来袭,这不得用python高清保存防止她被封禁

前言 大家早好、午好、晚好吖 ❤ ~ 环境使用: Python 3.8 解释器 Pycharm 编辑器 模块使用: requests 数据请求 第三方模块 pip install requests <工具> re <正则表达式模块> 安装python第三方模块: win R 输入 cmd 点击确定, 输入安装命令 pip install 模块…

密码学_AES加密算法

目录 简介 AES的加密过程如下&#xff08;以128位密钥为例&#xff09;&#xff1a; 异或运算 初始变换&#xff08;initial round&#xff09; 字节代换&#xff08;SubBytes&#xff09; 行位移&#xff08;ShiftRows&#xff09; 列混合&#xff08;MixColumns&#x…

Socket套接字(网络编程万字总结-附代码)

文章目录前言一、概念二、分类&#xff08;三类&#xff09;2.1 流套接字&#xff1a;使用传输层TCP协议2.2 数据报套接字&#xff1a;使用传输层UDP协议2.3 原始套接字三、UDP数据报套接字编程3.1 Java数据报套接字通信模型3.2 DatagramSocket API3.2.1 DatagramSocket 构造方…

Shell函数

1、 函数定义 格式一&#xff1a; function name() { Command sequence; } 格式二&#xff1a; name() { Command sequence); } 1、()内是没有参数的&#xff0c;他只是函数定义的固定格式。 2、第八行fun 是函数的调用(第一种方式) 2、 函数传参 1、在Shell中&#xff0c;调用…

Jina 实例秀|基于CLIP模型的跨模态视频搜索

不同于传统的关键词搜索&#xff0c;你不需要给每个视频素材人为地打上标签。使用开源产品 CLIP-as-service&#xff0c;输入画面的描述文本&#xff0c;直接搜索到对应的视频片段。CLIP 是一个强大的模型&#xff0c;能够很好地判别文本和图片是否相关&#xff0c;但将其集成到…

【LeetCode】验证二叉搜索树 [M]

98. 验证二叉搜索树 - 力扣&#xff08;LeetCode&#xff09; 一、题目 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。…

微信小程序框架02

目录 1.框架简介 2.视图层 View 2.2 WXML 2.3 WXSS 2.4 JS 3.事件 4.逻辑层 APP service 4.1 生命周期 4.2 页面路由 4.3模块化 1.框架简介 小程序开发框架的目标是通过尽可能简单、高效的方式让开发者可以在微信中开发具有原生 APP 体验的服务。 整个小程序框架系统分为两部…

山东大学机器学习课程资源索引

实验 完整实验代码获取 github repo 【ML实验4】多分类贝叶斯模型 【ML实验5】SVM&#xff08;手写数字识别、核方法&#xff09; 【ML实验6】K-means&#xff08;图像压缩&#xff09; 【ML实验7】人脸识别综合项目&#xff08;PCA、多分类SVM&#xff09; 一个PCA加速技巧 …

数据治理:企业数据治理蓝图

参考《一本书讲透数据治理》、《数据治理》等 文章目录企业数据治理体系企业数据治理9个要素企业数据治理4个层面企业数据治理之道企业数据治理之法企业数据治理之术企业数据治理之器企业数据治理体系 数据治理、数据管理、数据管控三者是什么关系&#xff1f;很多人都搞混&am…

【Spring(二)】IoC入门案例(XML版)

文章目录前言1.IoC入门案例总结前言 上篇文章我们讲了IOC和DI两个核心概念&#xff0c;本篇文章我们会在Spring的环境下来实现它们&#x1f4aa;&#x1f4aa;。 1.IoC入门案例 我们先来实现IoC也就是管理Bean的这套模式&#xff0c;我们先来说说这套程序应该怎么做&#xff0c…

深度学习Week12-训练自己的数据集(YOLOv5)

这周接着详细解析小白YOLOv5全流程-训练实现数字识别_牛大了2022的博客-CSDN博客_yolov5识别数字&#xff0c;上周入门教大家下载配置环境&#xff0c;如果没有的话请参考上周的文章深度学习Week11-调用官方权重进行检测&#xff08;YOLOv5&#xff09;_牛大了2022的博客-CSDN博…