LeetCode笔记|35.搜索插入位置(二分查找)

题目链接:

35. 搜索插入位置 - 力扣(LeetCode)

我的答案:
class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {

        int i = 0, j = nums.size() - 1;
        if (nums[i] == target)  return i;
        if (nums[j] == target)  return j;
        if (nums[i] > target) {
            nums.insert(nums.begin(), target);
            return 0;
        }
        if (nums[j] < target) {
            nums.insert(nums.begin() + nums.size(), target);
            return nums.size() - 1;
        }

        int mid = (i + j) / 2;
        while(mid != i) {
            if (nums[mid] == target)    return (i + j) / 2;
            else if(nums[mid] < target) {
                i = mid;
                mid = (i + j) / 2;
            }else {
                j = mid;
                mid = (i + j) / 2;
            }
        }
        nums.insert(nums.begin() + mid + 1, target);
        return mid+1;
    }
};

单独考虑边界情况,执行通过,但if条件判断太多,代码不够简洁

此外,在做题的时候,说是要插入不存在的元素,但并不需要真的插入,只需要输出插入位置即可!因为题目只需要输出与答案相符。

官方答案:

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {

        int left = 0, right = nums.size() - 1;
        while(left <= right) {
            int mid = (left + right) / 2;
            if (nums[mid] == target)    return mid;
            else if(nums[mid] < target) { //[mid + 1, right]
                left = mid + 1;
            }else {
                right = mid - 1; //[left, mid - 1]
            }
        }
        return left;
    }
};
知识点:

二分法

有序数组的查找,可考虑采用二分法

二分查找学习视频:8-1 「二分查找」的基本思想_哔哩哔哩_bilibili

相似题目:

374. 猜数字大小 - 力扣(LeetCode)

/** 
 * Forward declaration of guess API.
 * @param  num   your guess
 * @return          -1 if num is higher than the picked number
 *                  1 if num is lower than the picked number
 *               otherwise return 0
 * int guess(int num);
 */

class Solution {
public:
    int guessNumber(int n) {
        
        if(guess(n) == 0) return n; //判断边界,最后一个数

        unsigned int mid = (1 + n) / 2;
        unsigned int i = 1, j = n;
        while(true) {
            if(guess(mid) == 0) return mid;
            else if(guess(mid) == -1) { //猜的数字大了
                j = mid;
                mid = (i + j) / 2;
            }else { //猜的数字小了
                i = mid;
                mid = (i + j) / 2;
            }

        }

        
    }
};

注意:int最大值为2^31-1,题目中给出的n的最大值为2^31-1,但执行相加操作可能会超出最大值,发生整型溢出

解决方法:

将int 改为 unsigned int

或者

mid = i + (j - i) / 2;

知识点:

C/c++中 int、long、long long等取值范围:

unsigned int 0~4294967295

int -2147483648~2147483647

unsigned long 0~4294967295

long -2147483648~2147483647

long long的最大值:9223372036854775807

long long的最小值:-9223372036854775808

unsigned long long的最大值:18446744073709551615 //20位

704. 二分查找 - 力扣(LeetCode)

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int i = 0, j = nums.size() - 1;
        if (nums[i] == target)  return i;
        if (nums[j] == target)  return j;
        int mid = (i + j) / 2;
        while(mid != i) {
            if (nums[mid] == target)    return (i + j) / 2;
            else if(nums[mid] < target) {
                i = mid;
                mid = (i + j) / 2;
            }else {
                j = mid;
                mid = (i + j) / 2;
            }
        }
        return -1;
    }
};

使用left > right作为while循环终止判断的写法:

class Solution {
public:
    int search(vector<int>& nums, int target) {
 
        int left = 0, right = nums.size() - 1; //初始判断区间[left, right]
        while(left <= right) {
            int mid = (left + right) / 2;
            if (nums[mid] == target)    return mid;
            else if(nums[mid] < target) { //缩小区间为[mid+1, right]
                left = mid + 1;
            }else { //缩小区间为[left, mid - 1]
                right = mid -1;
            }
        }
        return -1;
    }
};

在数组中使用二分查找的前提:

① 数组具有随机访问特性

② 数组内元素有序(但不是有序的数组有时也可以使用二分查找)

35题精选回答提供的——

二分查找题解列表:
题型一:二分求下标(在数组中查找符合条件的元素的下标)

704、34、35、300、611、658、436、1237、1300、4

二分查找不一定是有序数组,如

旋转有序数组:33、81、153、154

山脉数组:852、1095

题型二:二分答案(在一个有范围的区间里搜索一个整数)

69、287、374、275、1283、1292

题型三:二分答案的升级版(每一次缩小区间的时候都需要遍历数组)

875、410、LCP 12、1011、1482、1552、209

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值