★ 算法OJ题 ★ 二分查找算法

Ciallo~(∠・ω< )⌒☆ ~ 今天,塞尔达将和大家一起做几道二分查找算法算法题 ~

❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️

澄岚主页: 椎名澄嵐-CSDN博客

算法专栏: ★ 优选算法100天 ★_椎名澄嵐的博客-CSDN博客

❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️

目录

[壹 力扣704 - 二分查找](#壹 力扣704 - 二分查找)

[1.1 题目](#1.1 题目)

[1.2 算法解析](#1.2 算法解析)

[1.3 撰写代码](#1.3 撰写代码)

[1.4 朴素二分查找模板](#1.4 朴素二分查找模板)

[贰 力扣34 - 在排序数组中查找元素的第⼀个和最后⼀个位置](#贰 力扣34 - 在排序数组中查找元素的第⼀个和最后⼀个位置)

[2.1 题目](#2.1 题目)

[2.2 算法解析](#2.2 算法解析)

[2.3 撰写代码](#2.3 撰写代码)

[2.4 二分查找模板](#2.4 二分查找模板)

[叁 力扣35 - 搜索插入位置](#叁 力扣35 - 搜索插入位置)

[3.1 题目](#3.1 题目)

[3.2 算法解析](#3.2 算法解析)

[3.3 撰写代码](#3.3 撰写代码)

[肆 力扣69 - x的平方根](#肆 力扣69 - x的平方根)

[4.1 题目](#4.1 题目)

[4.2 算法解析](#4.2 算法解析)

[4.3 撰写代码](#4.3 撰写代码)

[伍 力扣852 - 山峰数组的峰顶索引](#伍 力扣852 - 山峰数组的峰顶索引)

[5.1 题目](#5.1 题目)

[5.2 算法解析](#5.2 算法解析)

[5.3 撰写代码](#5.3 撰写代码)

[陆 力扣162 - 寻找峰值](#陆 力扣162 - 寻找峰值)

[6.1 题目](#6.1 题目)

[6.2 算法解析](#6.2 算法解析)

[6.3 撰写代码](#6.3 撰写代码)

[柒 力扣153 - 寻找旋转排序数组中的最小值](#柒 力扣153 - 寻找旋转排序数组中的最小值)

[7.1 题目](#7.1 题目)

[7.2 算法解析](#7.2 算法解析)

[7.3 撰写代码](#7.3 撰写代码)

[捌 力扣LCR173 - 点名](#捌 力扣LCR173 - 点名)

[8.1 题目](#8.1 题目)

[8.2 算法解析](#8.2 算法解析)

[8.3 撰写代码](#8.3 撰写代码)

[~ 完 ~](#~ 完 ~)


壹 力扣704 - 二分查找

1.1 题目

704. 二分查找 - 力扣(LeetCode)

1.2 算法解析

首先想到的暴力解法就是遍历数组 ,找到target,时间复杂度为O(N),那么有没有更快速的方法呢~

二分查找算法适用于有二段性的区间,比如一个值的左边比这个值小,右边比此值大,根据数学期望,中间值为最佳~

1.3 撰写代码

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

1.4 朴素二分查找模板

cpp 复制代码
while(left <= right)
{
    int mid = left + (right - left) / 2;
    if (......) 
        right = mid - 1;
    else if (......) 
        left = mid + 1;
    else 
        return ......;
}

贰 力扣34 - 在排序数组中查找元素的第⼀个和最后⼀个位置

2.1 题目

34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode)

2.2 算法解析

2.3 撰写代码

cpp 复制代码
class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        // 处理数组为空
        if(nums.size() == 0) return {-1, -1};
        // 1. 二分左端点
        int begin = 0;
        int left = 0, right = nums.size() - 1;
        while(left < right)
        {
            int mid = left + (right - left) / 2;
            if(nums[mid] < target) left = mid + 1;
            else right = mid;
        }
        // 判断是否有结果
        if(nums[left] != target) return {-1, -1};
        else begin = left; // 记录结果

        // 2. 二分右端点
        left = 0, right = nums.size() - 1;
        while(left < right)
        {
            int mid = left + (right - left + 1) / 2;
            if(nums[mid] <= target) left = mid;
            else right = mid - 1;
        }
        // 左端点有结果右端点一定有结果
        return {begin, right};
    }
};

2.4 二分查找模板

1. 二分左端点模板

cpp 复制代码
while(left < right)
{
    int mid = left + (right - left) / 2;
    if(......) left = mid + 1;
    else right = mid;
}

2. 二分右端点模板

cpp 复制代码
while(left < right)
{
    int mid = left + (right - left + 1) / 2;
    if(......) left = mid;
    else right = mid - 1;
}

叁 力扣35 - 搜索插入位置

3.1 题目

35. 搜索插入位置 - 力扣(LeetCode)

3.2 算法解析

3.3 撰写代码

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

肆 力扣69 - x的平方根

4.1 题目

69. x 的平方根 - 力扣(LeetCode)

4.2 算法解析

此题需要考虑边界情况, <1单独处理~

并且数据过大有溢出风险,要用long long来存~

4.3 撰写代码

cpp 复制代码
class Solution {
public:
    int mySqrt(int x) {
        if(x < 1) return 0; // 边界情况~
        int left = 1, right = x;
        while(left < right)
        {
            long long mid = left + (right - left + 1) / 2; // 防溢出
            if(mid * mid <= x) left = mid;
            else right = mid - 1;
        }
        return left;
    }
};

伍 力扣852 - 山峰数组的峰顶索引

5.1 题目

852. 山脉数组的峰顶索引 - 力扣(LeetCode)

5.2 算法解析

5.3 撰写代码

cpp 复制代码
class Solution {
public:
    int peakIndexInMountainArray(vector<int>& arr) {
        int left = 1, right = arr.size() - 2;
        while(left < right)
        {
            int mid = left + (right - left + 1) / 2;
            if(arr[mid] > arr[mid - 1]) left = mid;
            else right = mid - 1;
        }
        return left;
    }
};

陆 力扣162 - 寻找峰值

6.1 题目

162. 寻找峰值 - 力扣(LeetCode)

6.2 算法解析

无序数组有二段性时也可以使用二分查找算法~

6.3 撰写代码

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

柒 力扣153 - 寻找旋转排序数组中的最小值

7.1 题目

153. 寻找旋转排序数组中的最小值 - 力扣(LeetCode)

7.2 算法解析

7.3 撰写代码

cpp 复制代码
class Solution {
public:
    int findMin(vector<int>& nums) {
        int left = 0, right = nums.size() - 1;
        int n = nums[right];
        while (left < right)
        {
            int mid = left + (right - left) / 2;
            if (nums[mid] > n) left = mid + 1;
            else right = mid;
        }
        return nums[left];
    }
};

捌 力扣LCR173 - 点名

8.1 题目

LCR 173. 点名 - 力扣(LeetCode)

8.2 算法解析

8.3 撰写代码

cpp 复制代码
class Solution {
public:
    int takeAttendance(vector<int>& records) {
        int left = 0, right = records.size() - 1;
        while (left < right)
        {
            int mid = left + (right - left) / 2;
            if (records[mid] == mid) left = mid + 1;
            else right = mid;
        }
        if(records[left] == left) return left + 1;
        else return left;
    }
};

~ 完 ~

相关推荐
Erik_LinX3 分钟前
算法日记25:01背包(DFS->记忆化搜索->倒叙DP->顺序DP->空间优化)
算法·深度优先
Alidme10 分钟前
cs106x-lecture14(Autumn 2017)-SPL实现
c++·学习·算法·codestepbystep·cs106x
奔跑吧邓邓子10 分钟前
【Python爬虫(44)】分布式爬虫:筑牢安全防线,守护数据之旅
开发语言·分布式·爬虫·python·安全
小王努力学编程11 分钟前
【算法与数据结构】单调队列
数据结构·c++·学习·算法·leetcode
最遥远的瞬间12 分钟前
15-贪心算法
算法·贪心算法
菜还不练就废了25 分钟前
蓝桥杯刷题25.2.22|打卡
职场和发展·蓝桥杯
C#Thread26 分钟前
C#上位机--流程控制(IF语句)
开发语言·javascript·ecmascript
程序员 小濠35 分钟前
接口测试基础 --- 什么是接口测试及其测试流程?
自动化测试·python·测试工具·职场和发展·appium·接口测试·压力测试
万兴丶1 小时前
Unity 适用于单机游戏的红点系统(前缀树 | 数据结构 | 设计模式 | 算法 | 含源码)
数据结构·unity·设计模式·c#
牵牛老人1 小时前
Qt开发中出现中文乱码问题深度解析与解决方案
开发语言·qt