LeetCode 162.寻找峰值

思路:

1.题目规定了nums-1 = numsn = -∞,也就是假设nums0的左边还有一个-∞,numsn - 1的右边还有一个-∞。原因在于这样可以保证数组一定有峰值。比如数组是严格递减的,那么nums0就是(唯一的)峰值;同理如果数组是严格递增的,那么numsn - 1就是(唯一的)峰值。

2.分析:如果i < n - 1且numsi < numsi + 1,那么在下标i + 1,n - 1中一定存在峰值(如果不满足,那么一定有numsi + 1 < numsi + 2,numsi + 2 < numsi + 3,...,numsn - 1 < numsn = -∞,可知不成立,因此在下标i + 1,n - 1中一定存在峰值)。同理可知如果i < n - 1且numsi > numsi + 1,那么在下标0,i中一定存在峰值。

3.因此,可以通过二分的方式,通过比较numsi和numsi + 1的大小关系,不断地缩小存在峰值的范围,二分找到峰值。

4.注意:如果有多个峰值,我们无法在一开始、以及二分过程中就确定哪个峰值最终会成为答案。二分的思路只是不断地缩小范围,并最终找到其中的一个峰值。由于每次只关注mid和mid + 1的局部大小关系,然后根据这个局部信息决定是向左还是向右。不同的数组初始状态会导致算法走向不同的峰值。因此得到的峰值不一定是全局最高峰。

5.复杂度分析:

(1)时间复杂度:O(logn),其中n为nums的长度。

(2)空间复杂度:O(1)。

附代码:

java 复制代码
class Solution {
    public int findPeakElement(int[] nums) {
        int left = 0;
        int right = nums.length - 1; // 闭区间[0,n - 1]
        
        while (left < right) { // 此时区间至少还有两个元素
            int mid = left + (right - left) / 2;
            if (nums[mid] > nums[mid + 1]) {
                // 下坡,峰顶位置 <= mid
                right = mid;
            } else {
                // 上坡,峰顶位置 >= mid + 1
                left = mid + 1;
            }
        }
        return left;
    }
}

ACM模式:

java 复制代码
import java.util.Scanner;

class Solution {
    public int findPeakElement(int[] nums) {
        int left = 0;
        int right = nums.length - 1; // 闭区间[0, n - 1]

        while (left < right) { // 此时区间至少还有两个元素
            int mid = left + (right - left) / 2;
            if (nums[mid] > nums[mid + 1]) {
                // 下坡,峰顶位置 <= mid
                right = mid;
            } else {
                // 上坡,峰顶位置 >= mid + 1
                left = mid + 1;
            }
        }
        return left;
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // 读取数组长度
        int n = scanner.nextInt();

        // 读取数组元素
        int[] nums = new int[n];
        for (int i = 0; i < n; i++) {
            nums[i] = scanner.nextInt();
        }

        // 寻找峰值元素
        Solution solution = new Solution();
        int result = solution.findPeakElement(nums);
        System.out.println(result);

        scanner.close();
    }
}
相关推荐
2601_970703835 分钟前
工业除湿机租赁:把一份租金合同拆开看
大数据·数据结构·算法·数据库架构·推荐算法
心中有你02145 分钟前
Java实现Dijkstra最短路径算法(邻接表 + 优先队列)
java·数据库·算法
ZhengEnCi1 小时前
同样的模型,为什么本地和云 API 差别那么大:量化精度、聊天模板与采样参数的三大元凶
人工智能·算法·llm
Flynn Liang1 小时前
RAG 答非所问/幻觉怎么破?Spring AI QuestionAnswerAdvisor 召回优化实战(TopK/重排/混合检索)
人工智能·算法·spring·rag·幻觉·springai
liminla!2 小时前
SQL 从入门到进阶:语法速查与实战练习(完整优化版)
数据库·sql·算法
维克兜率天3 小时前
【维克】指数调整:哪些股票会被“强制买入“?
人工智能·python·算法
罗西的思考4 小时前
【轻量化复刻大模型】线性注意力交互式演示
人工智能·算法·机器学习
神也畏惧菠萝4 小时前
Day08 Python流程控制从入门到上瘾:if/match/while/for四件套,从B站登录一路打到猜数字游戏
python·算法·数据存储·for·while·if·ifelse
揽星河..4 小时前
【C语言】分支和循环
c语言·c++·算法