【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;
}

思路

【Leetcode】二分法求解问题_第1张图片

  • 当数组中有target时,直接使用正常的二分查找即可。
  • 当数组中没有target时,需要输出插入的位置,此时插入的位置只可能是0、5或是1~4。
  • 当插入位置为0时,到数第二步应指向该位置
    【Leetcode】二分法求解问题_第2张图片
    下一步right指向的下标为-1,返回right+1或left即可。
  • 当插入的位置为5时,到数第二步指向的位置应该为
    【Leetcode】二分法求解问题_第3张图片
    下一步left应该指向下标为5的位置,此时返回right+1或left即可。
  • 当插入的位置为其它时,到数第二步指向的位置应该是
    【Leetcode】二分法求解问题_第4张图片
    下一步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不相同的值。
    【Leetcode】二分法求解问题_第5张图片

你可能感兴趣的:(Leetcode,leetcode,算法,c语言)