当前位置: 首页 > news >正文

【Leetcode】二分法求解问题

目录

  • 704.二分查找
  • 35.搜索插入位置
    • 代码
    • 思路
  • 34.在排序数组中查找元素第一个和最后一个的位置
    • 代码
    • 思路:

  • 二分法必须用于以排好序的数组。

704.二分查找

如果对二分法没有了解,可以先看这个题

35.搜索插入位置

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

请必须使用时间复杂度为 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

提示:

  • 1 <= nums.length <= 104
  • 104 <= nums[i] <= 104
  • nums 为 无重复元素 的 升序 排列数组
  • 104 <= target <= 104

代码

int searchInsert(int* nums, int numsSize, int target){
    int left = 0, right = numsSize-1;
    while(left <= right)
    {
        int mid = left+((right-left)>>1);
        if(nums[mid] > target)
        {
            right = mid - 1;
        }
        else if(nums[mid] < target)
        {
            left = mid + 1;
        }
        else
        {
            return mid;
        }
    }
    return right+1;
    //return left;
}

思路

在这里插入图片描述

  • 当数组中有target时,直接使用正常的二分查找即可。
  • 当数组中没有target时,需要输出插入的位置,此时插入的位置只可能是0、5或是1~4。
  • 当插入位置为0时,到数第二步应指向该位置
    在这里插入图片描述
    下一步right指向的下标为-1,返回right+1或left即可。
  • 当插入的位置为5时,到数第二步指向的位置应该为
    在这里插入图片描述
    下一步left应该指向下标为5的位置,此时返回right+1或left即可。
  • 当插入的位置为其它时,到数第二步指向的位置应该是
    在这里插入图片描述
    下一步left指向下标为2的位置,此时跳出循环,返回left或right+1即可

34.在排序数组中查找元素第一个和最后一个的位置

给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。

如果数组中不存在目标值 target,返回 [-1, -1]。

你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。

示例1:

输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]

示例2:

输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]

示例3:

输入:nums = [], target = 0
输出:[-1,-1]

提示:

  • 0 <= nums.length <= 105
  • 109 <= nums[i] <= 109
  • nums 是一个非递减数组
  • 109 <= target <= 109

代码

int* searchRange(int* nums, int numsSize, int target, int* returnSize){
    int left =0,right = numsSize-1;
    *returnSize = 2;
    int* arr = (int*)malloc(2*sizeof(int));
    while(left<=right)
    {
        int center = left + ((right - left) >> 1);//防止溢出,与(left + right)/2;同意
        if(nums[center] == target)
        {
            int left = center - 1;
            int right = center + 1;
            while(left >= 0 && nums[left] == target)//确定所求数字在数组中最左边的下标
            {
                left--;
            }
            while(right <= numsSize-1 && nums[right] == target)//确定所求数字在数组中最右边的下标
            {
                right++;
            }
            arr[0] = left + 1;
            arr[1] = right - 1;
            return arr;
        }
        else if(nums[center] > target)
        {
            right = center - 1;
        }
        else
        {
            left = center + 1;
        }
    }
    arr[0] = -1;
    arr[1] = -1;
    return arr;
}

思路:

  1. 使用常规的二分法查找数组中是否有目标值
  2. 有:使用left和right变量,将找到的目标值的下标将改下标的左右值分别赋给left和right,进行向左和向右的遍历,直到找到与target不相同的值。
    在这里插入图片描述

相关文章:

  • 还有哪些行业可以做垂直网站/管理方面的培训课程
  • wordpress 新手教程/sem竞价托管多少钱
  • 做购物网站表结构分析/怎么创建一个网站
  • vs做网站开发吗/兴安盟新百度县seo快速排名
  • 学做网站在哪里/搜搜
  • 阿里云虚拟主机网站/轻饮食网络推广方案
  • 22道js输出顺序问题,你能做出几道
  • 30 个 Python 技巧,加速你的数据分析处理速度
  • python爬虫-反爬-验证码
  • Python Tkinter Gui 常用组件介绍 基本使用
  • 1.3.5 手写数字识别之资源配置
  • While 与 do while 的区别
  • 基于Lua框架下的合宙ESP32C3+1.5‘’Eink墨水屏天气时钟+OLED开源项目分享
  • Python学习笔记(八)——递归函数和匿名函数
  • 这C语言代码,会让你发疯
  • IT部门全被裁?不懂业务,花了几百万开发的报表系统,根本没人看
  • JAVAEE中的线程安全的集合类(包括HashtableConcurrentHashMap)
  • Intel汇编-传送大量字符串