代码随想录学习第一天--二分查找

文章详细介绍了二分查找算法在处理有序数组时的应用,包括标准的二分查找以及处理有重复元素的情况。对于无重复元素的查找,重点在于区分区间定义。当存在重复元素时,区分查找第一次出现或最后一次出现目标元素的策略。文章还提到了LeetCode的相关编程题目作为实践示例。
摘要由CSDN通过智能技术生成

代码随想录学习第一天–二分查找

标准二分查找

给定数组array[n], 目标元素target

  1. 数组生序/降序排列。
  2. 无重复元素。

重点(升序):注意区间的定义,[left,right)还是[left,right]。

  1. [left,right)中left=right无意义,故循环结束条件为left==right。
    其中当array[mid]<target, 则 left=left+1;
    当array[mid]==target, 则找到target;
    当array[mid]>target, 则right=mid;这是由于array[mid]已经被排除,故新的区间不包括mid,即[left,mid)。
  2. [left,right]中left=right有意义,故循环结束条件为left<right。
    其中当array[mid]<target, 则 left=left+1;
    当array[mid]==target, 则找到target;
    当array[mid]>target, 则right=mid-1;这是由于array[mid]已经被排除,故新的区间不包括mid,即[left,mid-1]。

有重复元素的二分查找

给定数组array[n], 目标元素target,查找第一次出现target的位置。或者最后一次出现target的位置。

第一次出现target的位置

注意array[mid]==target时,不再跳出循环,而是继续从mid左侧查找target。
1.区间[left,right]中left=right有意义,故循环结束条件为left<right。
其中当array[mid]<target, 则 left=left+1;
当array[mid]==target, right=mid-1;(target已经出现,需要在mid左侧继续寻找)
当array[mid]>target, 则right=mid-1;这是由于array[mid]已经被排除,故新的区间不包括mid,即[left,mid-1]。
最终的left指向的位置为第一次出现target的位置。

最后一次出现target的位置

注意array[mid]==target时,不再跳出循环,而是继续从mid左侧查找target。
1.区间[left,right]中left=right有意义,故循环结束条件为left<right。
其中当array[mid]<target, 则 left=left+1;
当array[mid]==target, left=mid+1;(target已经出现,需要在mid左侧继续寻找)
当array[mid]>target, 则right=mid-1;这是由于array[mid]已经被排除,故新的区间不包括mid,即[left,mid-1]。
最终的left指向的位置为第一次出现target的位置。

转换

查找整数,最后一次出现target的位置 等于 第一次出现target+1的位置-1,可以将最后一次出现target的位置使用第一次出现target的位置的代码计算,以实现代码复用。

leetcode题目

35.搜索插入位置 (opens new window)
34.在排序数组中查找元素的第一个和最后一个位置 (opens new window)
69.x 的平方根
367.有效的完全平方数

代码示例

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

请必须使用时间复杂度为 O(log n) 的算法。

示例 1:

输入: nums = [1,3,5,6], target = 5
输出: 2
示例 2:

输入: nums = [1,3,5,6], target = 2
输出: 1
示例 3:

输入: nums = [1,3,5,6], target = 7
输出: 4

来源:力扣(LeetCode)
链接:[https://leetcode.cn/problems/search-insert-position]
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。*/

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        //二分查找搜索位置;注意区间的定义的不同需要判断的条件不同。
        //[left,right) left=mid+1,right=mid; while(left<right)
        //初始化left=0;rightright=nn;
        //mid= (left+right) /2;若最终未找到即[left right+1)->[left,left) 
        //看numss[left]与target的大小决定插入左边还是右边(实际不可能出现在右边) 
        int right=nums.size();
        int left=0;
        while(left<right)
        {
            int mid=(left+right)/2;
            if(nums[mid]==target) return mid;
            else if(nums[mid]<target)
            {
                left=mid+1;
            }
            else
            {
                right=mid;
            }
        }
        return left;
    }
};`
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值