【代码随想录】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开始的

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

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

目录
相关文章
|
7月前
代码随想录——双指针(一)
代码随想录——双指针(一)
|
算法
代码随想录刷题-数组双指针
代码随想录刷题-数组双指针
62 0
|
8月前
|
算法
代码随想录Day34 LeetCode T343整数拆分 T96 不同的二叉搜索树
代码随想录Day34 LeetCode T343整数拆分 T96 不同的二叉搜索树
62 0
|
8月前
|
存储
【每日一题Day294】LC88合并两个有序数组 | 双指针
【每日一题Day294】LC88合并两个有序数组 | 双指针
48 0
|
8月前
【每日一题Day306】LC228汇总区间 | 双指针
【每日一题Day306】LC228汇总区间 | 双指针
42 0
【Java每日一题,二分】P2249 【深基13.例1】查找
【Java每日一题,二分】P2249 【深基13.例1】查找
冒泡排序(简练版)(一看就懂)(对比选择排序)
冒泡排序(简练版)(一看就懂)(对比选择排序)
|
算法 Java
二叉树展开为链表(力扣热题HOT100 之 力扣114)Java
给你二叉树的根结点 root ,请你将它展开为一个单链表: 展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。 展开后的单链表应该与二叉树 先序遍历 顺序相同。
133 0
二叉树展开为链表(力扣热题HOT100 之 力扣114)Java
二叉树中的最大路径和(力扣热题HOT100 之 力扣124)java
路径 被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。
147 0
二叉树中的最大路径和(力扣热题HOT100 之 力扣124)java
|
容器
【代码随想录】LC 102. 二叉树的层序遍历
目录 一、题目 1、原题链接 2、题目描述 二、解题报告 1、思路分析 2、时间复杂度 3、代码详解 三、知识风暴
52 0