LeetCode二分查找总结
2014-07-14 13:28
330 查看
对3道二分查找题的总结,来源于:soulmachine,code_ganker
Search Insert Position
Search in Rotated Sorted Array
Search in Rotated Sorted Array II
1.最基本的二分查找:
思路就是每次取中间,如果等于目标即返回;否则根据大小关系切去一半。
因此算法复杂度是O(logn),空间复杂度O(1)。
【注意1】while条件为left<=right,若找不到目标,最后一次操作是left和right指向同一index,执行一次循环体;结束时left>right,左右指针位置颠倒。
【注意2】先写leftHalf,再写rightHalf
【注意3】"以上实现有一个好处:循环结束时,如果没找到目标,那么left一定停在恰好比目标大的index上,right一定停在恰好比目标小的index上,比较推荐这种实现。"
2.旋转数组的查找I:
基本二分查找比较mid的值,这里比较target是否在区间,别无特殊。
不用纠结于Array怎么无序的,关注于旋转后一定有half是有序的。
【注意1】条件必须是 A[left] <= A[mid],因为考虑到 left == mid 的case。例如:只写"<",那么考虑 A=[3,1], target=1 的测试用例,结果会是错误的"-1"。
【注意2】注意写区间时候按照[,)来写。判断target是否在有序的half里,思路较清楚。
至于为什么区间含left(或right)不含mid,因为target可能在两个边缘,如果在mid,就会直接return。
【注意3】条件写成 if ( A[left] > A[mid] ) -- else 也可以。
【注意4】关注于leftHalf是否有序,条件只能写成" if ( A[left] <= A[mid] ) -- else ",原因如上。(Soulmachine Ver.)
关注于rightHalf是否有序,条件可以写成" if ( A[mid] < A[right] ) -- else ",或" if ( A[mid] < A[right] ) -- else ",OJ均会accept。(Code_Ganker Ver.)
3.旋转数组的查找II:
和上题一样,只是因为元素重复,if(A[left]<=A[mid])不一定是有序的,需要将这个case拆解成两部分处理:
-若 A[left] < A[mid] ,按照有序处理;
-若 A[left] ==A[mid],left++,处理边缘再来查找就ok。
Search Insert Position
Search in Rotated Sorted Array
Search in Rotated Sorted Array II
1.最基本的二分查找:
思路就是每次取中间,如果等于目标即返回;否则根据大小关系切去一半。
因此算法复杂度是O(logn),空间复杂度O(1)。
<span style="font-size:12px;">public class Solution { public int searchInsert(int[] A, int target) { int left=0; int right=A.length-1; while(left<=right){//【注意1】 int mid=(left+right)/2; if(target==A[mid]) //find it! return mid; if (target<A[mid])//left half right=mid-1; else //right half left=mid+1; } return left;//should insert here【注意3】 } } </span>
【注意1】while条件为left<=right,若找不到目标,最后一次操作是left和right指向同一index,执行一次循环体;结束时left>right,左右指针位置颠倒。
【注意2】先写leftHalf,再写rightHalf
【注意3】"以上实现有一个好处:循环结束时,如果没找到目标,那么left一定停在恰好比目标大的index上,right一定停在恰好比目标小的index上,比较推荐这种实现。"
2.旋转数组的查找I:
基本二分查找比较mid的值,这里比较target是否在区间,别无特殊。
不用纠结于Array怎么无序的,关注于旋转后一定有half是有序的。
<span style="font-size:12px;">public class Solution { public int search(int[] A, int target) { int left=0; int right=A.length-1; while(left<=right){ //循环条件和基本二分查找一样 int mid=(left+right)/2; if(A[mid]==target) return mid; if(A[left]<=A[mid]){ //leftHalf有序【注意1】 if(A[left]<=target && target<A[mid])//【注意2】 right=mid-1; else left=mid+1; } else{ //既A[left]>A[mid],leftHalf无序【注意3】 if(A[mid]<target && target<=A[right]) left=mid+1; else right=mid-1; } } return -1; } }</span>
【注意1】条件必须是 A[left] <= A[mid],因为考虑到 left == mid 的case。例如:只写"<",那么考虑 A=[3,1], target=1 的测试用例,结果会是错误的"-1"。
【注意2】注意写区间时候按照[,)来写。判断target是否在有序的half里,思路较清楚。
至于为什么区间含left(或right)不含mid,因为target可能在两个边缘,如果在mid,就会直接return。
【注意3】条件写成 if ( A[left] > A[mid] ) -- else 也可以。
【注意4】关注于leftHalf是否有序,条件只能写成" if ( A[left] <= A[mid] ) -- else ",原因如上。(Soulmachine Ver.)
关注于rightHalf是否有序,条件可以写成" if ( A[mid] < A[right] ) -- else ",或" if ( A[mid] < A[right] ) -- else ",OJ均会accept。(Code_Ganker Ver.)
3.旋转数组的查找II:
和上题一样,只是因为元素重复,if(A[left]<=A[mid])不一定是有序的,需要将这个case拆解成两部分处理:
-若 A[left] < A[mid] ,按照有序处理;
-若 A[left] ==A[mid],left++,处理边缘再来查找就ok。
<span style="font-size:12px;">public class Solution { public boolean search(int[] A, int target) { int left=0; int right=A.length-1; while(left<=right){ int mid=(left+right)/2; if(A[mid]==target) return true; if(A[left]<A[mid]){ if(A[left]<=target && target<A[mid]) right=mid-1; else left=mid+1; } else if(A[left]==A[mid]){ left++; } else{ if(A[mid]<target && target<=A[right]) left=mid+1; else right=mid-1; } } return false; } }</span>【注意1】"对left移动一步,直到边缘和中间不在相等或者相遇,这就导致了会有不能切去一半的可能。所以最坏情况(比如全部都是一个元素,或者只有一个元素不同于其他元素,而他就在最后一个)就会出现每次移动一步,总共是n步,算法的时间复杂度变成O(n)。"
相关文章推荐
- [LeetCode]Search Insert Position (二分查找总结) Java Version
- leetcode第十四周解题总结--二分查找
- [LeetCode] Serch Insert Position (总结二分查找) Java version
- LeetCode-二分查找面试题目总结
- leetcode第十五周解题总结--二分查找(二)
- [leetcode]二分查找总结
- LeetCode:Search Insert Position,Search for a Range (二分查找,lower_bound,upper_bound)
- [算法][LeetCode]Search a 2D Matrix——二维数组的二分查找
- [算法][LeetCode]Search a 2D Matrix——二维数组的二分查找
- 【二分查找】学习总结
- 程序员面试题目总结--数组(二)【二分查找、找出给定数字出现次数、两个有序整型数组交集、找出数组中唯一的重复元素、判断数组中的数值是否连续相邻】
- 二分查找和字符串基本知识总结
- 查找(二):二分查找----<学习总结>
- 对排序的总结&&二分查找
- leetcode旋转数组查找 二分查找的变形
- LeetCode @ Search Insert Position 二分查找
- Leetcode 二分查找 Search a 2D Matrix
- 三大查找算法总结:二分查找,分块查找和哈希表查找。
- Leetcode 二分查找 Search Insert Position
- 查找算法总结之顺序查找、二分查找、静态树查找