Leetcode ☞ 35. Search Insert Position 【binary search 二分查找 模板】

来源:互联网 发布:照片编辑软件 编辑:程序博客网 时间:2024/05/22 11:36

35. Search Insert Position

My Submissions
Total Accepted: 95470 Total Submissions: 259096 Difficulty: Medium

Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.

You may assume no duplicates in the array.

Here are few examples.
[1,3,5,6], 5 → 2
[1,3,5,6], 2 → 1
[1,3,5,6], 7 → 4
[1,3,5,6], 0 → 0
















我的AC(4ms,前有34%):

<span style="font-size:18px;">int searchInsert(int* nums, int numsSize, int target) {    int low = 0, high = numsSize - 1, mid;    while(low <= high){        if (nums[low] > target)            return low;        if (nums[high] < target)            return high + 1;                mid = low + (high - low) / 2;        if (nums[mid] > target)            high = mid - 1;        else if (nums[mid] < target)            low = mid + 1;        else            return mid;    }}</span>


思路:

二分查找 +  每次都先判断target是否在【nums[low] , nums[high]】之间,不在就说明是需要插入在边界处。




二分查找代码模板(理解+背):

要点有三:

1、使用(low+high)/2会有整数溢出的问题(当low+high的结果大于表达式结果类型所能表示的最大值时)【atoi那个题时也遇到超出INT_MAX的情况】
这样,产生溢出后再/2是不会产生正确结果的,而low+((high-low)/2)不存在这个问题

2、while循环时,有等号

3、mid跟target的判断时,没等号,执行时是加/减1



非递归:

int binarySearch(int* nums, int numsSize, int target) {    int low = 0, high = numsSize - 1, mid;        while(low <= high){        mid = low + (high - low) / 2;                if (nums[mid] > target)            high = mid - 1;        else if (nums[mid] < target)            low = mid + 1;        else            return mid;    }    if(low > high)//没找到        return -1;}


递归实现:

int binary_search(int arr[],int low,int high,int key){    int mid = low + (high - low) / 2;if(low > high)return -1;else{        if(arr[mid] == key)return mid;else if (arr[mid] > key)return binary_search(arr, low, mid - 1, key);elsereturn binary_search(arr, mid + 1, high, key);    }}


以下内容 整理自:http://blog.csdn.net/int64ago/article/details/7425727/


对num[]={1,2,2,4,4,8,10}不减序列在区间[0,7)进行查找。

我总结的二分无非就4种情况:YES_LEFT、YES_RIGHT、NO_LEFT、NO_RIGHT,分别代表:能找到且返回最左边的数的位置(如查找4的时候返回位置3)、能找到且返回最右边的数的位置(如查找4的时候返回位置4)、不能找到且返回左边与其接近的数的位置(如查找3的时候返回位置2)、不能找到且返回右边与其接近的数的位置(如查找3的时候返回位置3)。下面是我总结调试的代码:


对于YES_LEFT或者NO_RIGHT

int bSearch(int begin, int end, int e)  {      int mid, left = begin, right = end;      while(left <= right)      {          mid = (left + right) >> 1;          if(num[mid] >= e) right = mid - 1;          else left = mid + 1;      }      return left;  } 


对于YES_RIGHT或者NO_LEFT

int bSearch(int begin, int end, int e)  {      int mid, left = begin, right = end;      while(left <= right)      {          mid = (left + right) >> 1;          if(num[mid] > e) right = mid - 1;          else left = mid + 1;      }      return right;  } 


      不做过多说明,单步调试自然会发现执行过程,要说明的是,两个程序都用了right = mid - 1; left = mid +1;用这个的前提是终止条件要是left <= right。要注意的是,有的二分查找不是只需要四种情况中的一种,而是组合使用,比如查找一个数,如果找到则×××不然则×××,如果是YES_LEFT || NO_RIGHT组合或者YES_RIGHT || NO_LEFT组合就直接用上面代码即可,否则就要综合用了,加一些判断等说明,因为用的时候不多,就不给出代码了,自己如果遇到可以试着写写,当成模板,以后直接用~

       现在,是不是觉得二分查找很容易呢?如果总结过的话……


0 0
原创粉丝点击