【数据结构与算法】查找波峰或者波谷

给定一个没有重复数字的数组,找出里面的波峰或者波谷,没有返回-1。如果有,那么波峰波谷的两侧是单调的。

思路是二分查找。返回的条件是找到的中间值比两边都大或者比两边都小。那么如果不满足就需要查找左边或者右边。在判断左右之前,我们需要先判断数组的类型,是包含波峰还是波谷,方法是检测前两个值,如果a[0]>a[1],那么是找波谷,否则找波峰。

下面只看波峰的情况,如果a[m-1] < a[m] < a[m+1],那么位于递增区间,此时应该往右,否则往左。波谷的情况类似。

这是存在波峰或者波谷的情况,假设原来的数组的是单调递增的或者单调递减的,那么就应该返回-1,如果用上面的逻辑就会越界,因为肯定每一次都是往某一个方向,最后就到了最边的那一个元素,此时用a[m-1]或者a[m+1]的时候会越界。那么一旦说m到了最边界,可以说肯定不存在了,只需要返回-1就行,如果存在肯定不会是最两边的元素,在到了最边的元素之前就已经return了,所以检测到到了最边的时候,就返回-1。

public class Main {

	public static void main(String[] args) {
		System.out.println(findPeak(new int[]{-200,-100,1,4,0}));
	}
	
	public static boolean isUp(int[] array, int m){
		return array[m - 1] < array[m] && array[m] < array[m + 1];
	}
	
	public static int findPeak(int[] array){
		if(array == null || array.length <= 2)
			return -1;
		int mark = 0;
		if(array[0] > array[1])
			mark = -1;
		else
			mark = 1;
		int start = 0, end = array.length - 1;
		while(start <= end){
			int m = (start + end) / 2;
			if(m == 0 || m == array.length - 1)
				return -1;
			if((array[m - 1] > array[m] && array[m + 1] > array[m]) || (array[m - 1] < array[m] && array[m + 1] < array[m])){
				return m;
			}
			//往左边
			if((isUp(array, m) && mark < 0) || (!isUp(array, m) && mark > 0)){
				end = m - 1;
			}else{//右边
				start = m + 1;
			}
		}
		return -1;
	}

}

    原文作者:查找算法
    原文地址: https://blog.csdn.net/u010900754/article/details/78138490
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞