题目描述
值互不相同:不用考虑重复值情况(要不然比较麻烦)
思路 & 代码
重点在于保证O(logn)的时间复杂度 看成两个数组:前半段 & 后半段。根据两个数组的极值来判断 target 在哪个数组,再进行判断即可。 先一次二分,找到前半段、后半段的分界下标。 再一次二分,找到在某半段中的 target 注意:要考虑极端情况:在下标0处旋转,相当于没有旋转。
class Solution { public int search ( int [ ] nums, int target) { int k = - 1 , low = 0 , top = nums. length - 1 ; while ( low <= top) { k = ( low + top) / 2 ; if ( k + 1 == nums. length || nums[ k] > nums[ k + 1 ] ) { break ; } if ( nums[ k] < nums[ 0 ] ) { top = k - 1 ; } else { low = k + 1 ; } } if ( target > nums[ nums. length- 1 ] || k == nums. length- 1 ) { return binary ( nums, 0 , k, target) ; } else { return binary ( nums, k+ 1 , nums. length- 1 , target) ; } } public int binary ( int [ ] nums, int left, int right, int target) { if ( left >= right) { if ( target == nums[ left] ) { return left; } return - 1 ; } int half = ( left+ right) / 2 ; if ( target == nums[ half] ) { return half; } else if ( target > nums[ half] ) { return binary ( nums, half+ 1 , right, target) ; } else { return binary ( nums, left, half- 1 , target) ; } }
}
更新版
class Solution { public int search ( int [ ] nums, int target) { int k = - 1 ; int left = 0 , right = nums. length - 1 ; while ( left <= right) { k = ( left + right) / 2 ; if ( k + 1 == nums. length || nums[ k] > nums[ k + 1 ] ) { break ; } if ( nums[ k] < nums[ 0 ] ) { right = k - 1 ; } else { left = k + 1 ; } } if ( target > nums[ nums. length - 1 ] || k == nums. length - 1 ) { return binary ( nums, 0 , k, target) ; } else { return binary ( nums, k + 1 , nums. length - 1 , target) ; } } public int binary ( int [ ] nums, int left, int right, int target) { if ( left > right) { return - 1 ; } int mid = ( left + right) / 2 ; if ( target == nums[ mid] ) { return mid; } else if ( nums[ mid] > target) { return binary ( nums, left, mid - 1 , target) ; } else { return binary ( nums, mid + 1 , right, target) ; } }
}