4242 * @param {number } target
4343 * @return {number }
4444 */
45+ /**@sponge
46+ * 解法一:暴力
47+ * 思路:将给定的数组还原成排序数组,再进行二分查找。
48+ * 但如果单纯用暴力解法还原数组需要从头到尾遍历所以需要O(n)的时间复杂度,可用下面方法简化成O(logn)
49+ * 1.找到第一个无序的位置还原成排序数组,用O(logn)实现,
50+ * 2.再用二分查找O(logn)
51+ * time:O(logn)
52+ * space:O(1)
53+ * runtime:72ms 56%
54+ * memory usage:33.3MB 100%
55+ */
56+ var search = function ( nums , target ) {
57+ if ( ! nums . length ) return - 1 ;
58+
59+ let l = 0 ;
60+ let r = nums . length - 1 ;
61+ let mid = 0 ;
62+ //暴力还原排序数组,找到第一个无序的位置(用二分查找实现)
63+ while ( l < r ) {
64+ mid = Math . floor ( ( l + r ) / 2 ) ;
65+ if ( nums [ mid ] > nums [ r ] ) {
66+ l = mid + 1 ;
67+ } else {
68+ r = mid ;
69+ }
70+ }
71+ //找到第一个无序的位置,即最小的值
72+ let min = l ;
73+ l = 0 ;
74+ r = nums . length - 1 ;
75+ //判断target是否在min~r之间
76+ if ( target <= nums [ r ] ) l = min ;
77+ else r = min - 1 ;
78+ //按二分查找模板搜索target
79+ while ( l <= r ) {
80+ mid = Math . floor ( ( l + r ) / 2 ) ;
81+ if ( nums [ mid ] == target ) return mid ;
82+ if ( nums [ mid ] < target ) l = mid + 1 ;
83+ else r = mid - 1 ;
84+ }
85+ return - 1 ;
86+ } ;
4587
4688/**@sponge
47- * 解法一:二分查找
48- * 根据nums[mid]与nums[l]的关系判断mid在左段还是右段
89+ * 解法二:二分查找
90+ * 根据nums[mid]与nums[r]的关系判断mid在左段还是右段,
91+ * 或者nums[mid]与nums[l]的关系判断mid在左段还是右段
4992 * 再判断target是在mid的左边还是右边
5093 * time:O(logn)
5194 * space:O(1)
95+ * runtime:72ms
96+ * memory usage:33.1MB
5297 */
53- var search = function ( nums , target ) {
98+ var search = function ( nums , target ) {
99+ if ( ! nums . length ) return - 1 ;
100+
54101 let l = 0 ;
55- let r = nums . length - 1 ;
102+ let r = nums . length - 1 ;
56103
57- while ( l <= r ) {
58- let mid = Math . floor ( ( l + r ) / 2 ) ;
59- if ( target == nums [ mid ] ) return mid ;
60- // 先根据 nums[mid] 与 nums[lo] 的关系判断 mid 是在左段还是右段
61- if ( nums [ mid ] >= nums [ l ] ) {
62- // 再判断 target 是在 mid 的左边还是右边,从而调整左右边界 lo 和 hi
63- if ( target >= nums [ l ] && target < nums [ mid ] ) {
64- r = mid - 1 ;
104+ while ( l <= r ) {
105+ let mid = Math . floor ( ( l + r ) / 2 ) ;
106+ if ( target == nums [ mid ] ) return mid ;
107+ // 先根据 nums[mid] 与 nums[r] 的关系判断 mid 是在左段还是右段
108+ if ( nums [ mid ] < nums [ r ] ) {
109+ // 再判断 target 是在 mid 的左边还是右边,从而调整左右边界 l 和 r
110+ // mid ~ r 之间有序
111+ if ( target > nums [ mid ] && target <= nums [ r ] ) {
112+ l = mid + 1 ;
65113 } else {
66- l = mid + 1 ;
114+ r = mid - 1 ;
67115 }
68116 } else {
69- if ( target > nums [ mid ] && target < = nums [ r ] ) {
70- l = mid + 1 ;
117+ if ( target < nums [ mid ] && target > = nums [ l ] ) {
118+ r = mid - 1 ;
71119 } else {
72- r = mid - 1 ;
120+ l = mid + 1 ;
73121 }
74- }
75-
122+ }
123+
76124 }
77125 return - 1 ;
78126} ;
79- // @lc code=end
80-
127+ // @lc code=end
0 commit comments