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 searchRange(vector& 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&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&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:大于小于情况写反了。

你可能感兴趣的:(leetcode,数组,二分查找)