算法--求先递增后递减数组最大值的下标
2017-10-21 14:48
211 查看
题目:
给定数组a, 里面的元素先严格递增后严格递减, 求最大值元素的下标.
分析:
看到这道题目的时候, 我脑海中首先浮现出现的是爬山坡. "先递增"就是爬坡, "后递减"就是下坡, 而要找的最大值就是"峰顶". 而"严格"二字表明数组中不包含重复数字. OK, 我想最简单的思路就是, 遍历一遍, 找到第一个满足条件a[i]>a[i+1]的元素, 表明开始"下坡", 则i就是所找的最大值下标. 这种解法的时间复杂度为O(n). 当然, 这其中存在两种情况, 需要单独拿出来分析一下: 1, 数组单调递增. 因为题目要求数组"先递增后递减", 如果是"单调递增"的话, 那么最后一个元素, 肯定大于倒数第二个元素. 2, 数组单调递减. 同第一种情况的分析, "单调递减"的该数组, 肯定满足条件a[0]>a[1].
所以, 时间复杂度为O(n)的解法如下:
OK, 其实, 问题在此已经可以完美解决了. 但是我们就不能更进一步吗? 为什么不考虑一下时间复杂度为O(logn)的情况呢?
满足时间复杂度O(logn)的查找算法, 你想到了什么呢? 二分查找. 那么查找的"峰顶"元素会满足什么样的条件呢? "峰顶"嘛, 大于左侧元素, 也大于右侧元素, 即a[i] > a[i-1] && a[i] > a[i+1].
所以, 时间复杂度为O(logn)的解决方法为:
PS:
最后, 如果给定数组并不是严格先递增后递减的, 即其中含有相同的元素, 该怎么办?
这里只给出引申, 不再给出具体代码, 大家可以思考一下.
给定数组a, 里面的元素先严格递增后严格递减, 求最大值元素的下标.
分析:
看到这道题目的时候, 我脑海中首先浮现出现的是爬山坡. "先递增"就是爬坡, "后递减"就是下坡, 而要找的最大值就是"峰顶". 而"严格"二字表明数组中不包含重复数字. OK, 我想最简单的思路就是, 遍历一遍, 找到第一个满足条件a[i]>a[i+1]的元素, 表明开始"下坡", 则i就是所找的最大值下标. 这种解法的时间复杂度为O(n). 当然, 这其中存在两种情况, 需要单独拿出来分析一下: 1, 数组单调递增. 因为题目要求数组"先递增后递减", 如果是"单调递增"的话, 那么最后一个元素, 肯定大于倒数第二个元素. 2, 数组单调递减. 同第一种情况的分析, "单调递减"的该数组, 肯定满足条件a[0]>a[1].
所以, 时间复杂度为O(n)的解法如下:
int findPeak(int[] nums) { if (nums != null && nums.length > 0) { if (nums.length == 1) { return 0; } if (nums[0] > nums[1]) {//数组单调递减 return 0; } int index = nums.length-1; if (nums[index] > nums[index-1]) {//数组单调递增 return index; } //循环n-1次 for (int i = 0; i < index; i++) { if (nums[i] > nums[i+1]) { return i; } } } return -1; }
OK, 其实, 问题在此已经可以完美解决了. 但是我们就不能更进一步吗? 为什么不考虑一下时间复杂度为O(logn)的情况呢?
满足时间复杂度O(logn)的查找算法, 你想到了什么呢? 二分查找. 那么查找的"峰顶"元素会满足什么样的条件呢? "峰顶"嘛, 大于左侧元素, 也大于右侧元素, 即a[i] > a[i-1] && a[i] > a[i+1].
所以, 时间复杂度为O(logn)的解决方法为:
int findPeak(int[] nums){ if (nums != null && nums.length > 0) { if (nums.length == 1) { return 0; } if (nums[0] > nums[1]) {//数组单调递减 return 0; } int index = nums.length-1; if (nums[index] > nums[index-1]) {//数组单调递增 return index; } int i = 0, j = index; int mid = 0; while (i < j) {//二分查找 mid = (i + j) / 2; if (nums[mid] > nums[mid - 1] && nums[mid] > nums[mid + 1]) { return mid; } else if (nums[mid] > nums[mid + 1]) {//处于下坡段, 即递减段 j = mid - 1; } else if (nums[mid] > nums[mid - 1]) {//处于上坡段, 即递增段 i = mid + 1; } } } return -1; }
PS:
最后, 如果给定数组并不是严格先递增后递减的, 即其中含有相同的元素, 该怎么办?
这里只给出引申, 不再给出具体代码, 大家可以思考一下.
相关文章推荐
- 求先递增在递减数组中的最大值
- 算法跨语言/*从一维数组100个数据中选出最大10个数的下标及最小6个数的下标*/
- ] 找工作知识储备(2)---数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 算法题:最大递增数组个数
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- (核心算法)查找某个数在有序数组中(递增,含重复)第一次出现的下标
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 一个数组的值先从小到大递增后从大到小递减,找出最大的值
- 找工作知识储备---数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 找工作知识储备(2)---数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 算法3:找出一个整数数组里面两个查值最大的两个下标a[j]-a[i]最大并且i<j
- 一个数组的值先从小到大递增后从大到小递减,找出最大的值
- 一个数组的值先从小到大递增后从大到小递减,找出最大的值
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- [算法]数组中求出下标不连续的任意个数,使得和最大
- 一个数组的值先从小到大递增后从大到小递减,找出最大的值 .
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串 (转)