leetcode刷题:数组-二分查找

理论笔记:

1、使用C++:

注意vector 和 array的区别,vector的底层实现是array,严格来讲vector是容器,不是数组

2、数组元素不能删只能覆盖

Q1:在有序数组中查找给定数字。

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

int search(int* nums, int numsSize, int target){
  int left,right,middle;
  left = 0;
  right = numsSize-1;

  while(left <= right){
      middle = (left + right)/2;
      if(nums[middle] < target){
          left = middle + 1;
      }
      else if (nums[middle] > target){
          right = middle - 1;
      }

      else return middle;

  }

  return -1;



}

错误1:应该要有三个int型;使用while;

错误2:分清楚左闭右闭和左闭右开

错误3:return直接跳出调用函数,后面程序不再执行

Q2:升序无重复数组搜索或插入数字

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

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

      else return middle;

  }

    return left ;
}

错误1:返回位置错了;多写几个例子,或者举极端例子

Q3:在有序数组中查找某一元素的左右边界

34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode) (leetcode-cn.com)

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        int leftboundary = searchLeftRange(nums,target);
        int rightboundary = searchRightRange(nums,target);
        if(leftboundary == -2||rightboundary == -2) return{-1,-1};
        if(rightboundary - leftboundary > 1)   return{leftboundary + 1,rightboundary - 1};
        return{-1,-1};
    }

private:
int searchLeftRange(vector<int>&nums,int target){
    int left,right,middle;
    int leftboundary = -2;
    left = 0;
    right = nums.size() - 1;
    
    while(left <= right){
      middle = (left + right)/2;
      if(nums[middle] < target){
          left = middle + 1;
      }
      else  {
          right = middle - 1;
          leftboundary = right;
      }      
 }
    return leftboundary;
}

 int searchRightRange(vector<int>&nums,int target){
    int left,right,middle;
    int rightboundary = -2;
    left = 0;
    right = nums.size() - 1;

     while(left <= right){
      middle = (left + right)/2;
      if(nums[middle] > target){
          right = middle - 1;
      }
      else  {
          left = middle + 1;
          rightboundary =left;
      }
 }
    return rightboundary;
}
};

思路:将传统的二分查找三种合并成两种从而确定左右边界

错误1:举例子算到最后确定返回值+1或者-1的情况

错误2:没考虑好情况,超出范围和在范围内但是查找不到混成一种情况,但实际上是不一样的。不在范围内,leftboundry或者rightboundry始终有一个没修改,但是在范围内却没有的情况,两个的值都会修改,只不过差值=1。

Q4:不使用特殊运算符计算整数的平方根,舍去小数部分

69. x 的平方根 - 力扣(LeetCode) (leetcode-cn.com)

int mySqrt(int x){
    if(x == 0)  return 0;
    int left,right,middle;
    left = 1;
    right = x ;
    while(left <= right){
        middle = left + (right - left)/2;
        if(middle == x / middle) return middle;

        if(middle < x / middle){
            left = middle + 1;
        }

        if(middle > x / middle){
            right = middle - 1;
        }
    }

    return right;
}

思路:采用二分法,以及整数除法与本题的完美适应度

错误1:左右初始值赋值错误,跟数组还不一样,从1开始而不是从0开始

错误2:注意返回值。因为都是舍去小数所以最后取较小值right。

Q5:判断一个整型数字是否为完全平方数

367. 有效的完全平方数 - 力扣(LeetCode) (leetcode-cn.com)

bool isPerfectSquare(int num){
    int left,right,middle,t;
    left = 1;
    right = num;

    while(left <= right){
        middle = left + (right - left)/2;
        t = num / middle;

        if(t == middle) {
            if(num % t == 0)    return true;
            else left = middle + 1;
        }
        if(t > middle)   left = middle + 1;
        if(t < middle)   right = middle - 1;
    }
    
    return false;
}

思路:二分法

错误一:没看到给出的num范围,middle直接平方会越界。所以采取和上一个题目一样的除法(除法就不会越界)。

错误2:大于小于情况写反了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值