题意
给一个有序数组,然后从数组的某一个位置,将前后两半交换。现在给一个数k,求k在数组中出现的位置,如果没有出现,返回-1。
思路
算法1
画个图,其实就两种情况:前半段长还是后半段长,然后分若干种情况去讨论。
讨论结果如下:
-
k>am
:
- am>ar:right
-
am<ar:
- k<ar:right
- k>ar:left
-
k<am:
- am<ar:left
-
am>ar:
- k<ar:right
- k>ar:left
然后取等号的情况判断一下就好。
算法2
思路同之前的Find Minimum in Rotated Sorted Array
- k=am: 返回m即可
-
k≠am
:
-
am<ar
:说明右边是有序的。
- am<k≤ar:right
- else:left
-
am>ar
:说明左边是有序的。
- al≤k<ar:left
- else:right
-
am<ar
:说明右边是有序的。
代码
//algorithm1
class Solution {
public:
int search(vector<int>& a, int k) {
int n = a.size();
int l = 0, r = n - 1, m;
while (l <= r) {
m = l + (r - l >> 1);
if (a[m] == k) return m;
if (k > a[m]) {
if (a[m] > a[r]) l = m + 1;
else {
if (k == a[r]) return r;
if (k < a[r]) l = m + 1;
else r = m - 1;
}
} else {
if (a[m] < a[r]) r = m - 1;
else {
if (a[r] == k) return r;
else if (k < a[r]) l = m + 1;
else r = m - 1;
}
}
}
return -1;
}
};
//algorithm 2
class Solution {
public:
int search(vector<int>& a, int k) {
int n = a.size();
int l = 0, r = n - 1, m;
while (l <= r) {
m = l + (r - l >> 1);
if (a[m] == k) return m;
if (a[m] < a[r]) {
if (a[m] < k && k <= a[r]) l = m + 1;
else r = m - 1;
} else {
if (a[l] <= k && k < a[m]) r = m - 1;
else l = m + 1;
}
}
return -1;
}
};