IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> LeetCode——1.数组1:二分查找(35.搜索插入位置) -> 正文阅读

[数据结构与算法]LeetCode——1.数组1:二分查找(35.搜索插入位置)

?

目录

数组

二分查找

方法

35.搜索插入位置


?

数组

数组是存放在连续内存空间上的相同类型数据的集合。

数组可以方便的通过下标索引的方式获取到下标下对应的数据。

633d512e3fc8420c8285dbe6ec7b7430.png

注意

  • 数组下标是从0开始的
  • 数组的地址是连续的
  • 在删除或者增加数组元素时,数组元素不能删除只能覆盖,所以要移动元素

二分查找

使用条件

  1. 数组元素要有序的
  2. 有的题也会出现有重复元素的情况

二分法的边界问题比较重要,关于区间的定义一般有两种,一种是左闭右闭[left,right],第二种左闭右开[left,right),这就涉及到循环条件和right值的处理不同

mid防止溢出:

左闭右闭[left,right]:int mid = left + ((right - left) / 2);

左闭右开[left,right):int mid = left + ((right - left) >> 1);

方法

以LeetCode?704.二分查找为例

给定一个?n?个元素有序的(升序)整型数组?nums 和一个目标值?target ?,写一个函数搜索?nums?中的 target,如果目标值存在返回下标,否则返回 -1。

1.左闭右闭[left,right]

target在[left,right]区间内,所以left=right是有意义的,所以,循环条件和right值的处理:

  • while (left <= right)?
  • if (nums[middle] > target) right 要赋值为 middle - 1,因为当前这个nums[middle]一定不是target(因为右面是闭区间,所以target和left比较过了),那么接下来要查找的左区间结束下标位置就是 middle - 1

例:查找元素1

90bd1f4b17ae47a99f8ee302803808e2.png

704.二分查找的Java代码

class Solution {
    public int search(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        while (left <= right) {
            int mid = left + ((right - left) / 2); //为了防止溢出,和(left+right)/2一样
            if(nums[mid] < target) {
                left = mid + 1;
            }else if(nums[mid] > target) {
                right = mid - 1;
            }else if(nums[mid] == target) {
                return mid;
            }
        }
        return -1;
    }
}

2.左闭右开[left,right)

target在[left,right)区间内,所以left=right没有意义的,所以,循环条件和right值的处理:

  • while (left <right)?
  • right要指向nums.length
  • if (nums[middle] > target) right 更新为 middle,因为当前nums[middle]不等于target,去左区间继续寻找,而寻找区间是左闭右开区间,所以right更新为middle,即:下一个查询区间不会去比较nums[middle] (因为右区间是开的,所以如果right更新为middle-1,就比较不到当前的right值了。在左区间进行寻找)

例:查找1元素

6f04e5ced4794ed88da5dc9e1360c9f2.png

704.二分查找的Java代码

class Solution {
    public int search(int[] nums, int target) {
        int left = 0;
        int right = nums.length;
        while (left < right) {
            int mid = left + ((right - left) >> 1); //为了防止溢出
            if(nums[mid] < target) {
                left = mid + 1;
            }else if(nums[mid] > target) {
                right = mid;
            }else if(nums[mid] == target) {
                return mid;
            }
        }
        return -1;
    }
}

35.搜索插入位置

题目链接

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

上面的母题会了之后,这道题就很简单了,思路基本一样,唯一的不同就是当目标值不存在时函数的返回值。这里也可以讨论两种区间的情况。

1.左闭右闭[left,right]

前面的思路一样,现在来还原最差的情况(最后一次循环):目标值不存在。例:查找元素2

c4a3949f38904d619aa6d371170a09fd.png

模拟最后一次left=right的循环,mid指向的值小于目标值2,所以left会更新为mid+1,此时的值就是目标值应该在的位置,让函数值返回left。找目标值7的时候同理。

Java代码

class Solution {
    public int searchInsert(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        while(left <= right){
            int mid = left + ((right - left) / 2);
            if(target < nums[mid]) {
                right = mid - 1;
            }else if (target > nums[mid]) {
                left = mid + 1;
            }else {
                return mid;
            }
        }
        return left; //或者return right+1;
    }
}

2.左闭右开[left,right)

还原最差的情况(最后一次循环):目标值不存在,例:查找元素7?

bd86b40500de4042be3aa226ca312e38.png

此时是最后一次循环的情况,mid指向的值小于目标值,所以left会向右移一位,所以,函数的返回值是left/right均可。

Java代码

class Solution {
    public int searchInsert(int[] nums, int target) {
        int left = 0;
        int right = nums.length;
        while(left < right){
            int mid = left + ((right - left) >> 1);
            if(target < nums[mid]) {
                right = mid;
            }else if (target > nums[mid]) {
                left = mid + 1;
            }else {
                return mid;
            }
        }
        return right; //或者return left;
    }
}

?

?

?

?

?

?

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-09-04 01:36:44  更:2022-09-04 01:38:57 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 18:10:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码