查找序列最宽尖峰——含代码

问题来自一个在线测试,其实是挺简单的问题,但是过分追求效率了,不想添加太多额外数据结构,结果花了好多时间还没答对,回头想了想,先把正确的方法写了再说吧!

问题描述:

有一个数组,[1, 3, 1, 2, 5, 4, 3, 1, 9, 10],按照数值的大小进行高低排列,如下:

                5

    3      2      4         10

1       1            3    9

                           1

可以看到最宽的尖峰是由第三个数1开始到第7个数1结束,所以我们的函数要输出 3 7,如果没有尖峰,则输出-1 -1;


思路:找到每一个尖峰的最高点,对最高点的信息进行记录,最高点前面有几个数,最高点后面有几个数,建立两个附加数组,Up和Down,长度和输入序列相同,只当某一位是最高点时,才在两个数组中记录,up[i]表示第i位数是一个最高点,在第i位数之前的上升序列有多长,同理,down[i]表示i之后的下降序列有多长,最后遍历两个数组在同一位上求和找最大值


附上代码:

public class FindWidthestGap {
    public static void main(String[] args) {
        findGap(new int[] { 1, 3, 1, 2, 5, 4, 3, 1, 9, 10 });
        findGap(new int[] { 1, 2, 3, 4, 5, 4, 3, 1, 9, 10 });
        findGap(new int[] { 1, 2, 3, 4, 5, 4, 3, 2, 1 });
        findGap(new int[] { 1, 3, 1, 2, 5, 4, 3, 1, 0, -1 });
        findGap(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
        findGap(new int[] { 9, 8, 7, 6, 5, 4, 3, 2, 1 });
        findGap(new int[] { 1,2,1});
    }

    public static void findGap(int[] arr) {
        int len = arr.length;
        if(len<3){
            System.out.println("-1 -1");
        }
        int[] up = new int[len];
        int[] down = new int[len];
        int pos = 0;
        int lastPos = 0;
        while (pos < len - 1) {
            while (pos < len - 1 && arr[pos] <= arr[pos + 1]) {
                pos++;
            }
            up[pos] = pos - lastPos;
            lastPos = pos;
            while (pos < len - 1 && arr[pos] > arr[pos + 1]) {
                pos++;
            }
            down[lastPos] = pos - lastPos;
            lastPos = pos;
        }
        int max = -1;
        int begin = -1;
        int end = -1;
        for (int i = 0; i < len; i++) {
            if (up[i] != 0 && down[i] != 0) {
                int sum = up[i] + down[i];
                if (max < sum) {
                    max = sum;
                    begin = i - up[i];
                    end = i + down[i];
                }
            }
        }
        System.out.println(begin + " " + end);
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值