leetcode 35 搜索插入的位置

题目:https://leetcode-cn.com/problems/search-insert-position/

思路一:二分法查找(在循环体的内部查找元素

分析:
因为是一个有序数组,先找到中间位置,(注意,如果是偶数,中间位置选用左边的),然后用中间位置的值和目标值进行比较,如果比目标值大,就在数 组中间值左半部分找,反之,进在右半部分找;如果和目标值相等,就返回下标,直到指向右边位置的指针(low)大于指向左面位置的指针(high),就结束 (说 明数组里面没有和目标值相同的值);这就会出现三种情况:目标值比数组的最大值大,这时low的值大于数组的长度-1;目标值比数组的最小值小, 这 时high比0小;目标值位于数组中两个元素中间,这时low的范围在【0,len-1】之间,low的位置就是插入的位置。
即归结为四种情况:

  • 目标值在数组所有元素之前

  • 目标值等于数组中某一个元素

  • 目标值插入数组中的位置

  • 目标值在数组所有元素之后

步骤:
1、定义两个变量分别指向数组的左右两个端点(用于表示查找的范围)
2、如果右端点小于等于左端点,就执行循环体
3、计算数组的中点值的下标,如果中间值比目标值小,则右端点等于中间值的下标+1;如果中间值比目标值大,则将左端点的值等于中间值的下标-1;否则,就 返 回(中间值和目标值相等),就返回下标
4、如果执行完循环体没有找到中间值和目标值相等的下标,则low>high;如果右下标比数组的最后一位元素的下标大(目标值比数组的最大的值大),则返回数 组 的最后一位元素的下标+1(数组的长度);如果左端点比0小(目标值比数组0号位置的数小),则返回数组的0号位置;否则(目标值在数组的两个元素之 间),给返回low;

class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
    int len = nums.size();
       //采用左闭右闭的区间
    int low = 0;//指向数组的左右边
    int high = len-1;//指向数组的最左面
    while (low <= high)
    {
        int midaum =high+(high-low)>>1
        if (nums[midaum] < target)
        {
            low = midaum + 1;
        }
        else if (nums[midaum] > target)
        {
            high = midaum - 1;
        }
        else
        {
            return midaum;
        }
    }
    if (low>len-1)
    {
        return len ;
    }
    else if(high<0)
    {
        return 0;
    }
    else
    {
        return low;
    }
}
};

思路二:二分法

分析:
在这里插入图片描述

int searchInsert(vector<int>& nums, int target) {
    int len = nums.size();
    int low = 0;
    int high = len-1;
    int ans=len;
    while (low <= high)
    {
        int mid=((high-low)>>1)+low;
        if(target<=nums[mid])
        {
            ans=mid;
            high=mid-1;
        }
        else
        {
            low=mid+1;
        }
    }
    return ans;
  }

思路三:二分法(在 循环体内部排除元素)

  1. while(left < right) 这种写法表示在循环体内部排除元素;

  2. 退出循环的时候 left 和 right 重合,区间 [left, right] 只剩下成 1 个元 素,退出循环,这个元素 有可能
    就是我们要找的元素。

  3. 采用左闭右闭的区间

int searchInsert(vector<int> &nums, int target) {
       int size = nums.size();
       if (size == 0) {
              return 0;
       }
       // 特判
       if (nums[size - 1] < target) {
              return size;
       }
       int left = 0;
       int right = size - 1;
       while (left < right) {
              int mid = left + (right - left) / 2;
              // 严格小于 target 的元素一定不是解
              if (nums[mid] < target) {
                     // 下一轮搜索区间是 [mid + 1, right]
                     left = mid + 1;
              }
              else {
                     // 下一轮搜索区间是 [left, mid]
                     right = mid;
              }
       }
       return left;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值