publicintminArray(int[] numbers){ int min = numbers[0]; for (int i = 1; i < numbers.length; i++) { if (min > numbers[i]){ min = numbers[i]; } } return min; }
privatestaticclassSolution2{ publicintminArray(int[] numbers){ int i = 0, j = numbers.length - 1; while (i < j) { int m = (i + j) / 2; if (numbers[m] > numbers[j]) { i = m + 1; } elseif (numbers[m] < numbers[j]) { j = m; } else { j--; } } return numbers[i]; } }
时间复杂度 :O(log 2N) : 在特例情况下(例如 [1, 1, 1, 1]),会退化到 O(N)。 空间复杂度 :O(1) : i , j , m 变量使用常数大小的额外空间。
二分法优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
publicintminArray(int[] numbers){ int i = 0, j = numbers.length - 1; while (i < j) { //主要是在这一步进行了优化,防止溢出 int m = i+ (j - i) / 2; if (numbers[m] > numbers[j]) { i = m + 1; } elseif (numbers[m] < numbers[j]) { j = m; } else { j--; } } return numbers[i]; }
追加
输入一个递减排序的数组的一个旋转,求最大值(最小值)
求最大值
同样的思路:
numbers[m] > numbers[j]
那么这个最大值一定在m的右侧
1
j = m
numbers[m] < numbers[j]
那么这个最大值一定在m的左侧
1
i = m + 1;
numbers[m] == numbers[j]
1
j--
实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
private static class Solution { public int minArray(int[] numbers) { int i = 0, j = numbers.length - 1; while (i < j) { int m = i+ (j - i) / 2; if (numbers[m] > numbers[j]) { j = m; } else if (numbers[m] < numbers[j]) { i = m +1; } else { j--; } } return numbers[i]; } }
privatestaticclassSolution3{ publicintminArray(int[] numbers){ int max = numbers[0]; for (int i = 1; i < numbers.length; i++) { if (max < numbers[i]) { max = numbers[i]; } } return max; } }