问题来自一个在线测试,其实是挺简单的问题,但是过分追求效率了,不想添加太多额外数据结构,结果花了好多时间还没答对,回头想了想,先把正确的方法写了再说吧!
问题描述:
有一个数组,[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);
}
}