牛客网高频算法题系列-BM19-寻找峰值

牛客网高频算法题系列-BM19-寻找峰值

题目描述

给定一个长度为n的数组nums,请你找到峰值并返回其索引。数组可能包含多个峰值,在这种情况下,返回任何一个所在位置即可。

  1. 峰值元素是指其值严格大于左右相邻值的元素。严格大于即不能有等于
  2. 假设 nums[-1] = nums[n] = -\infty−∞
  3. 对于所有有效的 i 都有 nums[i] != nums[i + 1]
  4. 你可以使用O(logN)的时间复杂度实现此问题吗?

原题目见:寻找峰值

解法一:数组遍历

首先,判断几种特殊场景:

  • 如果数组为空,则不存在峰值;
  • 如果数组只有一个元素,因为都是负无穷,所以第一个元素即为峰值;
  • 如果数组的第一个元素比第二个元素大,加上左边负无穷,则第一个元素必为峰值;
  • 如果数组的最后一个元素比倒数二个元素大,加上右边边负无穷,则倒数第一个元素必为峰值。

如果不存在以上特殊情况,则从数组的第二位开始遍历数组,判断是否是峰值。

解法一:二分法

原理:因为左右都是负无穷,对于中间的元素,如果nums[mid] > nums[mid + 1],也就是mid部分递减,加上左边负无穷,所以mid的左边一定会有峰值;同理,如果nums[mid] < nums[mid + 1],加上右边负无穷,所以mid的右边一定会有峰值。

代码
public class Bm019 {

    /**
     * 遍历数组
     *
     * @param nums
     * @return
     */
    public static int findPeakElement(int[] nums) {
        // 如果数组为空,则不存在峰值
        if (nums == null) {
            return -1;
        }
        // 如果数组的长度为1,则首位即为峰值
        if (nums.length == 1) {
            return 0;
        }
        // 如果第一位比第二位大,则第一位必为峰值
        if (nums[0] > nums[1]) {
            return 0;
        }
        // 如果最后一位比倒数第二位大,则最后一位必为峰值
        if (nums[nums.length - 1] > nums[nums.length - 2]) {
            return nums.length - 1;
        }
        // 如果前面的几种特殊场景不存在,则遍历数组中的元素,逐一判断是否是峰值
        for (int i = 1; i < nums.length - 1; i++) {
            if (nums[i] > nums[i - 1] && nums[i] > nums[i + 1]) {
                return i;
            }
        }
        return -1;
    }

    /**
     * 二分法
     * 原理:因为左右都是负无穷,对于中间的元素,如果nums[mid] > nums[mid + 1],就是mid部分递减,加上左边负无穷,
     * 所以mid的左边一定会有峰值;同理,如果nums[mid] < nums[mid + 1],加上右边负无穷,所以mid的右边一定会有峰值。
     *
     * @param nums
     * @return
     */
    public static int findPeakElement2(int[] nums) {
        // 如果数组为空,则不存在峰值
        if (nums == null) {
            return -1;
        }
        // 如果数组的长度为1,则首位即为峰值
        if (nums.length == 1) {
            return 0;
        }
        // 如果第一位比第二位大,则第一位必为峰值
        if (nums[0] > nums[1]) {
            return 0;
        }
        // 如果最后一位比倒数第二位大,则最后一位必为峰值
        if (nums[nums.length - 1] > nums[nums.length - 2]) {
            return nums.length - 1;
        }

        int left = 1, right = nums.length - 2;
        while (left < right) {
            int mid = (left + right) / 2;
            if (nums[mid] > nums[mid + 1]) {
                right = mid;
            } else {
                left = mid + 1;
            }
        }
        return left;
    }

    public static void main(String[] args) {
        int[] nums = {2, 4, 1, 2, 7, 8, 4};
        System.out.println(findPeakElement(nums));
        System.out.println(findPeakElement2(nums));
    }
}

1.0 1 365 ≈ 37.7834343329 1.01^{365} ≈ 37.7834343329 1.0136537.7834343329
0.9 9 365 ≈ 0.02551796445 0.99^{365} ≈ 0.02551796445 0.993650.02551796445
相信坚持的力量!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是使用SVD-FRFT算法抑制海杂波的高频地波雷达Matlab代码: ```matlab % 假设海杂波数据为x,雷达数据为y % 设置分数阶阶数和傅里叶重构参数 order = 1.5; frft_param = 0.5; % 对海杂波和雷达数据分别进行SVD-FRFT变换 [Ux, Sx, Vx] = svd_frft(x, order); [Uy, Sy, Vy] = svd_frft(y, order); % 对海杂波和雷达数据进行傅里叶重构变换 rx = ifrft(Sx, Vx, frft_param); ry = ifrft(Sy, Vy, frft_param); % 计算海杂波和雷达数据的协方差矩阵 Cx = cov(rx, ry); % 对协方差矩阵进行SVD分解 [U, S, V] = svd(Cx); % 计算特征值和特征向量 eig_vals = diag(S); eig_vecs = V; % 将海杂波和雷达数据的SVD-FRFT系数矩阵进行重构 Sx_new = Sx * eig_vecs(1, 2:end)'; Sy_new = Sy * eig_vecs(1, 2:end)'; % 对重构后的SVD-FRFT系数矩阵进行傅里叶重构 rx_new = ifrft(Sx_new, Vx, frft_param); ry_new = ifrft(Sy_new, Vy, frft_param); % 将抑制后的雷达数据和海杂波数据相减 output_data = y - rx_new; % 输出抑制后的雷达数据 disp(output_data); ``` 上述代码中,`svd_frft`函数用于实现SVD-FRFT变换,`ifrft`函数用于进行傅里叶重构变换。代码中首先对海杂波和雷达数据进行SVD-FRFT变换,并进行傅里叶重构变换。然后计算海杂波和雷达数据的协方差矩阵,并对其进行SVD分解,得到特征值和特征向量。接着将海杂波和雷达数据的SVD-FRFT系数矩阵进行重构,并对重构后的系数矩阵进行傅里叶重构。最后将抑制后的雷达数据和海杂波数据相减,得到抑制后的雷达数据。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

醉舞经阁-半卷书

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值