[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 高频考题整理确实是很有帮助的,以下是一些常见的 Leetcode 高频考题整理: 1. 数组和字符串问题: - 两数之和 (Two Sum) - 三数之和 (Three Sum) - 最长回文子串 (Longest Palindromic Substring) - 盛最多水的容器 (Container With Most Water) - 下一个排列 (Next Permutation) 2. 链表问题: - 反转链表 (Reverse Linked List) - 删除链表中的倒数第N个节点 (Remove Nth Node From End of List) - 合并两个有序链表 (Merge Two Sorted Lists) - 链表中环的检测 (Linked List Cycle) - 环形链表的起始点 (Linked List Cycle II) 3. 树和图问题: - 二叉树的遍历 (Binary Tree Traversal) - 二叉树的最大深度 (Maximum Depth of Binary Tree) - 二叉树的最小深度 (Minimum Depth of Binary Tree) - 图的深度优先搜索 (Depth First Search) - 图的广度优先搜索 (Breadth First Search) 4. 动态规划问题: - 爬楼梯 (Climbing Stairs) - 最大子序和 (Maximum Subarray) - 打家劫舍 (House Robber) - 不同路径 (Unique Paths) - 最长递增子序列 (Longest Increasing Subsequence) 5. 排序和搜索问题: - 快速排序 (Quick Sort) - 归并排序 (Merge Sort) - 二分查找 (Binary Search) - 搜索旋转排序数组 (Search in Rotated Sorted Array) - 寻找峰值 (Find Peak Element) 这只是一些常见的 Leetcode 高频考题整理,还有很多其他题目也值得关注。通过刷题和整理高频题目,可以提高对算法和数据结构的理解和应用能力。希望对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值