从给定范围内的数组中查找峰值

时间:2014-03-26 13:53:52

标签: java arrays algorithm

方法getPeakCountint数组和范围(int)作为输入,并返回大于所有元素的整数数量范围。

例如,考虑数组{1,4,2,6,4,5,10,8,7,11}和范围2。结果应为3,因为{..,4,2,6,4,5,..}{..,4,5,10,8,7,..}{..,8,7,11}符合此条件。这些条件满足条件,因为61011都大于左右两个元素。

请注意,对于111等角落元素,无需分别检查左侧和右侧。

我的代码如下,但不正确。

static int getPeakCount(int[] arr, int R) {
        int result=0;
        for(int i=0;i<arr.length;i++){
        if(i==0){
            if(arr[i]>arr[i+1]&&arr[i]>arr[i+2]){
                result++;
            }
             } //-----> closing if(i==0) condition
            else if(i==arr.length-1){
                if(arr[i]>arr[i-1]&&arr[i]>arr[i-2]){
                    result++;
                }

            }
            else if(i+R>arr.length){
                if(arr[i]>arr[i-R] && arr[i]>arr[i-R+1]){
                    System.out.println(arr[i]);
                    result++;
                }
            }
            else{

                if(arr[i]>arr[i+1] && arr[i]>arr[i+2] && arr[i]>arr[i-R] && arr[i]>arr[i-R+1]){
                    System.out.println(arr[i]);
                    result++;
            }
        }
    }
    return result;
}

我不知道我是否正朝着正确的方向前进,如果条件不好,那么它会抛出java.lang.ArrayIndexOutOfBoundsException

P.S。不要将此代码视为从中删除错误的解决方案。这只是我尝试过的尝试。

3 个答案:

答案 0 :(得分:2)

我认为正确的想法和devnull是对的。您只需要检查中心,因此将循环更改为从结束前的1和结束1开始。我评论了最终条件。我认为这就是你所要求的,尽管不是100%肯定我明白你的意思。

我应该补充一下,为了清楚起见,我使用了l(左),r(右)和c(中)等变量。如果你有大型数组,你可以更快地做到这一点。还有一个冗余,它检查它应该知道的条件已经是假的(如果我找到一个峰值,我应该跳过下一个值,因为它也不能是一个峰值。)

public class PeakChecker {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        int[] array = new int[]{1, 4, 2, 6, 4, 5, 10, 8, 7, 11};

        System.out.println(nPeaks(array, 2));
    }

    static int nPeaks(int[] array, int range) {

        // Check for special cases
        if (array == null) {
            return 0;
        }

        int result = 0, l, r;

        // Check main body
        for (int i = 0; i < array.length; i++) {
            boolean isPeak = true;
            // Check from left to right
            l = Math.max(0, i - range);
            r = Math.min(array.length - 1, i + range);
            for (int j = l; j <= r; j++) {
                // Skip if we are on current
                if (i == j) {
                    continue;
                }
                if (array[i] < array[j]) {
                    isPeak = false;
                    break;
                }
            }

            if (isPeak) {
                System.out.println("Peak at " + i + " = " + array[i]);
                result++;
                i += range;
            }
        }

        return result;
    }
}

答案 1 :(得分:0)

最后一个if条件在i == arr.length - 2时抛出异常。

这是因为在这种情况下arr[i+2]超出范围。

答案 2 :(得分:0)

如果您读取ArrayIndexOutOfBoundsException堆栈跟踪,它将告诉您发生错误的一行代码。查看那行代码,您可能会看到arr [i + 1]或arr [i-1]或其他内容。当然,该线路上的至少一次访问将超出范围。这就是问题所在。