class Solution {
public int findMin(int[] nums) {
int l = 0;
int r = nums.length - 1;
int ans = nums[0];
while (l <= r) {
int m = (l + r) / 2;
if (nums[l] < nums[m]) {
if (nums[m] < nums[r]) {
ans = Math.min(ans, nums[l]);
r = m - 1;
} else {
ans = Math.min(ans, nums[r]);
l = m + 1;
}
} else { // 有可能 m==l 所以 nums[l] >= nums[m]
ans = Math.min(ans, nums[m]);
ans = Math.min(ans, nums[r]);
r = m - 1;
}
}
return ans;
}
}
class Solution {
public int findMin(int[] nums) {
int l = 0;
int r = nums.length - 1;
int ans = nums[0];
while (l <= r) {
int m = (l + r) / 2;
if (nums[l] < nums[m]) {
if (nums[m] < nums[r]) {
ans = Math.min(ans, nums[l]);
r = m - 1;
} else if (nums[m] > nums[r]){
ans = Math.min(ans, nums[r]);
l = m + 1;
} else { // nums[m] == nums[r]
ans = Math.min(ans, nums[l]);
r --;
}
} else if (nums[l] > nums[m]) {
ans = Math.min(ans, nums[m]);
r = m - 1;
} else { // nums[l] == nums[m]
ans = Math.min(ans, nums[l]);
ans = Math.min(ans, nums[r]);
l ++;
}
}
return ans;
}
}
这个用暴力找竟然时间更小。。。
看了答案应该这样写,减少了Math.min的比较时间
class Solution {
public int findMin(int[] nums) {
int l = 0;
int r = nums.length - 1;
while (l <= r) {
int m = (l + r) / 2;
if (nums[m] < nums[r]) {
// r = m - 1;
r = m;
} else if (nums[m] > nums[r]) {
l = m + 1;
} else { // nums[m] == nums[r]
r --;
}
}
return nums[l];
}
}
class Solution {
public int findPeakElement(int[] nums) {
int l = 0;
int r = nums.length - 1;
int m = 0;
while (l <= r) {
m = (l + r) / 2;
if (m == l) {
if (nums[m] < nums[r]) m = r; // r==l + 1
break; // r==l 或者 r==l+1 且 nums[l] 大
}
if (nums[m] > nums[m - 1]) { // 上坡或者坡顶
l = m;
} else { // 下坡
r = m - 1;
}
}
return m;
}
}
class MajorityChecker {
List<Integer>[] nums = new ArrayList[20001];
int max = 0;
public MajorityChecker(int[] arr) {
for (int i = 0; i < arr.length; i ++) {
if (nums[arr[i]] == null) {
nums[arr[i]] = new ArrayList<Integer>();
}
nums[arr[i]].add(i);
max = Math.max(max, arr[i]);
}
}
public int query(int left, int right, int threshold) {
int sum = 0;
int total = right - left + 1;
for (int i = 0; i <= max; i ++) {
if (nums[i] == null) continue;
int num = getNum(i, left, right);
if (num >= threshold) {
return i;
}
sum += num;
if (sum >= (total + 1) / 2) {
return -1;
}
}
return -1;
}
public int getNum(int num, int left, int right) {
List<Integer> tmp = nums[num];
int l = 0;
int r = tmp.size() - 1;
if (tmp.get(r) < left || tmp.get(l) > right) {
return 0;
}
while (l < r) {
int m = (l + r) >> 1;
if (tmp.get(m) >= left) {
r = m;
} else {
l = m + 1;
}
}
int fro = r;
if (tmp.get(fro) > right) {
return 0;
}
l = r;
r = tmp.size() - 1;
while (l < r) {
int m = (l + r) >> 1;
if (tmp.get(m) <= right) {
l = m + 1;
} else {
r = m - 1;
}
}
int end = 0;
if (l > 0) {
end = tmp.get(l) <= right ? l : l - 1;
}
return end - fro + 1;
}
}
/**
* Your MajorityChecker object will be instantiated and called as such:
* MajorityChecker obj = new MajorityChecker(arr);
* int param_1 = obj.query(left,right,threshold);
*/