[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;
	}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值