其实这个题是 https://leetcode-cn.com/problems/find-in-mountain-array/ 的一部分: 比如,array = [1,2,3,4,5,3,1],这个数组是由严格递增和严格递减的两个有序数组构成的,它的 peek 就是 5. 现在我改一下条件,要么这个数组是严格递增和严格递减的两个有序数组构成的(这种情况返回 peek 的索引),要么这个数组就只是一个严格递增或严格递减的数组(返回-1 )。
很明显,寻找 peek 可以用二分查找。
然后我发现这个算法有两种写法:
public int findArrayPeek(int[] array) {
int low = 0, high = array.length-1;
int middle = -1;
while (low <= high && (middle = (low + high)/2)-1 > 0 && middle+1 < array.length) {
if (array[middle-1] < array[middle] && array[middle] > array[middle+1]) {
return middle;
} else if (array[middle-1] < array[middle] && array[middle] < array[middle+1]) {
low = middle+1;
} else {
high = middle-1;
}
}
return -1;
}
@Test
public void findArrayPeekTest() {
int[] array = {1,2,3,4,5,3,1};
System.out.println(findArrayPeek(array));
int[] array1 = {0,1,2,4,2,1};
System.out.println(findArrayPeek(array1));
int[] array2 = {0,1,2,4,5,1};
System.out.println(findArrayPeek(array2));
int[] array3 = {0,1,2,4,5,6};
System.out.println(findArrayPeek(array3));
int[] array4 = {6,5,4,3,2,1};
System.out.println(findArrayPeek(array4));
}
首先是标准的二分查找,但循环条件中必须要上索引的保护。
public int findArrayPeek1(int[] array) {
int low = 0, high = array.length-1;
while (low < high-1) {
int middle = (low + high)/2;
if (array[middle-1] < array[middle] && array[middle] > array[middle+1]) {
return middle;
} else if (array[middle-1] < array[middle] && array[middle] < array[middle+1]) {
low = middle;
} else {
high = middle;
}
}
return -1;
}
@Test
public void findArrayPeek1Test() {
int[] array = {1,2,3,4,5,3,1};
System.out.println(findArrayPeek1(array));
int[] array1 = {0,1,2,4,2,1};
System.out.println(findArrayPeek1(array1));
int[] array2 = {0,1,2,4,5,1};
System.out.println(findArrayPeek1(array2));
int[] array3 = {0,1,2,4,5,6};
System.out.println(findArrayPeek1(array3));
int[] array4 = {6,5,4,3,2,1};
System.out.println(findArrayPeek1(array4));
}
然后是另外一种写法如上,它的处理过程从low = middle+1;
变成了low = middle;
,这里循环条件也必须得变,但这里不用加索引保护。
这两个算法,变化的只有对 low high 的处理,和循环条件。但感觉原理有点不一样,但我又说不清楚。。。(这种说不清楚的感觉,应该是我没有彻底弄懂~)
或者说,对 low high 的处理怎么影响这个过程的,相应的循环条件应该怎么写?
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.