【代码随想录】LC 704. 二分查找

简介: 防止溢出可以将int mid = (left + right) / 2;改为 int mid = left + ((right - left) / 2);或int mid = left + ((right - left) >> 1);。数组理论基础数组下标都是从0开始的数组在内存空间的地址是连续的数组中的元素只能覆盖,不能删除。

一、题目

1、原题链接

704. 二分查找


2、题目描述

b161e16bb32888c7bc18adbc0802a024_b74e9426f2ce4ed18a238f20cfdbe429.png


二、解题报告

1、思路分析

二分查找有一般有两种写法,主要思想是利用搜索区间的定义来确定代码条件:


[left,right](左闭右闭)

如果将区间定义为左闭右闭,则意味着left和right的值都可以取到,而且left和right的值可以相等。所以:

初始left=0、right=nums.size()-1。

循环条件需要设置为left<=right

当nums[mid]>target时,更新right=mid-1。(因为根据区间定义,此时如果使right=mid,区间可以取到mid,而已知mid不满足条件,故应将区间缩小为[left,mid-1])

当nums[mid]<target时,更新为left=mid+1。(因为根据区间定义,此时如果使left=mid,区间可以取到mid,而已知mid不满足条件,故应将区间缩小为[mid+1,right])

当nums[mid]==target时,返回mid。

否则,返回-1。

[left,right)(左闭右开)

如果将区间定义为左闭右开,则意味着left的值可以取到,而right的值取不到,而且left和right的值不可以相等。所以:

初始left=0、right=nums.size()。

循环条件需要设置为left<right

当nums[mid]>target时,更新right=mid。(因为根据区间定义,此时如果使right=mid-1,区间取不到mid-1,会使搜索区间丢失mid-1,故应将区间缩小为[left,mid))

当nums[mid]<target时,更新left=mid+1。(因为根据区间定义,此时如果使left=mid,区间可以取到mid,而已知mid不满足条件,故应将区间缩小为[mid+1,right))

当nums[mid]==target时,返回mid。

否则,返回-1。

2、时间复杂度

二分查找时间复杂度为O (log n)


3、代码详解

左闭右闭区间定义代码


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);
            //或
            //int mid = left + ((right - left) >> 1);
            int mid = (left + right) / 2;
            if (nums[mid] > target) right = mid - 1;
            else if (nums[mid] < target) left = mid + 1;
            else return mid;
        }
        return -1;
    }
};


左闭右开区间定义代码


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


三、知识风暴

注意mid是下标不是值,与target比较时是用nums[mid]。

防止溢出可以将int mid = (left + right) / 2;改为 int mid = left + ((right - left) / 2);或int mid = left + ((right - left) >> 1);。

数组理论基础

数组下标都是从0开始的

数组在内存空间的地址是连续的

数组中的元素只能覆盖,不能删除。

目录
相关文章
|
8月前
|
算法 Java
[Java·算法·简单] LeetCode 14. 最长公共前缀 详细解读
[Java·算法·简单] LeetCode 14. 最长公共前缀 详细解读
54 0
|
8月前
|
算法
代码随想录Day34 LeetCode T343整数拆分 T96 不同的二叉搜索树
代码随想录Day34 LeetCode T343整数拆分 T96 不同的二叉搜索树
64 0
【Java每日一题,二分】P2249 【深基13.例1】查找
【Java每日一题,二分】P2249 【深基13.例1】查找
|
容器
【代码随想录】LC 102. 二叉树的层序遍历
目录 一、题目 1、原题链接 2、题目描述 二、解题报告 1、思路分析 2、时间复杂度 3、代码详解 三、知识风暴
53 0
【代码随想录】LC 150. 逆波兰表达式求值
目录 一、题目 1、原题链接 2、题目描述 二、解题报告 1、思路分析 2、时间复杂度 3、代码详解 三、知识风暴 字符串转数字,数字转字符串
81 0
|
Go
leetcode-每日一题1408. 数组中的字符串匹配(暴力枚举)和Golang里关于Index方法和Contains方法区别
题目要求我们找到字符串数组中存在字符串是其他单词的子字符串,看到题目给我们的n的范围是[1,100],所以我们可以通过暴力枚举用两个for循环一层指子串一层指找存在这个子串的单词,找到则找下个一个子串
156 0
leetcode-每日一题1408. 数组中的字符串匹配(暴力枚举)和Golang里关于Index方法和Contains方法区别
|
存储 算法 索引
代码随想录刷题|LeetCode KMP算法理论 28. 实现 strStr() 459.重复的子字符串
代码随想录刷题|LeetCode KMP算法理论 28. 实现 strStr() 459.重复的子字符串
代码随想录刷题|LeetCode KMP算法理论 28. 实现 strStr() 459.重复的子字符串
回文字串(力扣热题HOT100 之 力扣647)java多种方法
给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。
108 0
|
C++ Python
LeetCode每日一题题解:1706. 球会落何处-题解-python && C++源代码
LeetCode每日一题题解:1706. 球会落何处-题解-python && C++源代码
LeetCode每日一题题解:1706. 球会落何处-题解-python && C++源代码
|
C++ Python
LeetCode每日一题题解:16. 最接近的三数之和-题解-python && C++源代码
LeetCode每日一题题解:16. 最接近的三数之和-题解-python && C++源代码