[LeetCode] Find Peak Element

A peak element is an element that is greater than its neighbors.

Given an input array where num[i] ≠ num[i+1], find a peak element and return its index.

The array may contain multiple peaks, in that case return the index to any one of the peaks is fine.

You may imagine that num[-1] = num[n] = -∞.

For example, in array [1, 2, 3, 1], 3 is a peak element and your function should return the index number 2.

Note:

Your solution should be in logarithmic complexity.

由于有对数时间的要求,容易让人想到二分思想。毕竟这里只需要返回任意一个peak。

另外这题有些不严谨,将peak定义为了必须大于其邻居。如此一来,如果所有的数组元素都相同,则没有定义这种情况下的返回值。这里测试用例里面没有包括这种情况。我们可以假设两个相邻元素不存在相等的情况,所以在二分比较的时候<=和<没有区别。

刚开始做的时候将第一个元素和最后一个元素当成了特例,优先单独考虑了。之后二分的情况只针对2个元素以上的数组。二分情况可以这样考虑:

1)如果当前元素在3个连续数里为极大值,即为所求;

2)如果3个连续数单调递增,则往右找;

3)如果3个连续数单调递减,则往左找;

4)如果当前元素在3个连续数里为极大值,则往任意两个方向找均可。

为了简化代码,其中3)和4)可以合并到一起。

	public int findPeakElement2(int[] num) {
		int length = num.length;
		if (length == 1) {
			return 0;
		} else if (length == 2) {
			return num[0] >= num[1] ? 0 : 1;
		}

		if (num[0] > num[1])
			return 0;
		else if (num[length - 1] > num[length - 2]) {
			return length - 1;
		}

		int low = 1, high = length - 2;
		while (low < high && low > 0 && high < length - 1) {
			int mid = low + (high - low) / 2;
			if (num[mid] >= num[mid - 1] && num[mid] >= num[mid + 1]) {
				return mid;
			} else if (num[mid - 1] <= num[mid] && num[mid] <= num[mid + 1]) {
				low = mid + 1;
			} else {
				high = mid - 1;
			}
		}

		return low;
	}

其实可以不用单独考虑第一个元素和最后一个元素,修改下循环里的if语句,代码可以更简洁:

	public int findPeakElement(int[] num) {
		int length = num.length;
		if (length == 1)
			return 0;

		int low = 0, high = length - 1;
		int mid = 0;
		while (low <= high) {
			mid = low + (high - low) / 2;
			if ((mid == 0 || num[mid] >= num[mid - 1])
					&& (mid == length - 1 || num[mid] >= num[mid + 1])) {
				return mid;
			} else if (mid > 0 && num[mid - 1] >= num[mid]) {
				high = mid - 1;
			} else {
				low = mid + 1;
			}
		}

		return mid;
	}

你可能感兴趣的:(LeetCode,element,find,peak)