Java 从给定范围内的数组中查找峰值
方法Java 从给定范围内的数组中查找峰值,java,arrays,algorithm,Java,Arrays,Algorithm,方法getPeakCount将int数组和一个范围(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}满足此条件。这些满足条件是因为6、10和11都大于其左右两个元素 请注意,对于角元素,如1和11,无需分别检查左侧和右侧 我的代码如下,但不正确 static int get
getPeakCount
将int
数组和一个范围(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}
满足此条件。这些满足条件是因为6
、10
和11
都大于其左右两个元素
请注意,对于角元素,如1
和11
,无需分别检查左侧和右侧
我的代码如下,但不正确
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;
}
static int getPeakCount(int[]arr,int R){
int结果=0;
对于(int i=0;iarr[i+1]&&arr[i]>arr[i+2]){
结果++;
}
}//--->如果(i==0)条件关闭
否则如果(i==arr.length-1){
if(arr[i]>arr[i-1]&arr[i]>arr[i-2]){
结果++;
}
}
否则如果(i+R>arr.length){
if(arr[i]>arr[i-R]&arr[i]>arr[i-R+1]){
系统输出打印项数(arr[i]);
结果++;
}
}
否则{
如果(arr[i]>arr[i+1]&arr[i]>arr[i+2]&arr[i]>arr[i-R]&arr[i]>arr[i-R+1]){
系统输出打印项数(arr[i]);
结果++;
}
}
}
返回结果;
}
我不知道我的方向是否正确,最后一个if条件是抛出java.lang.ArrayIndexOutOfBoundsException
不要将此代码视为解决此错误的解决方案。这只是我尝试的尝试。最后一个if条件将在
I==arr.length-2
时引发异常
这是因为在这种情况下,
arr[i+2]
超出范围。如果读取ArrayIndexOutOfBoundsException堆栈跟踪,它将告诉您一行发生错误的代码。看看这行代码,你可能会看到arr[i+1]或arr[i-1]之类的东西。当然,那条线上至少有一条通道是禁止进入的。这就是问题所在。我认为这个想法是正确的,德夫努尔是正确的。您只需要检查中心,因此将循环更改为从1开始,在结束之前结束1。我注释掉了结束条件。我想这正是你所要求的,尽管我不能100%肯定我理解你的意图
我应该补充一下,为了清晰起见,我使用了像l(左)、r(右)和c(中)这样的变量。如果您有大型阵列,则可以更快地执行此操作。还有冗余,它检查应该知道的条件已经为假(如果我发现一个峰值,我应该跳过下一个值,因为它不可能也是峰值)
公共级PeakChecker{
/**
*@param指定命令行参数
*/
公共静态void main(字符串[]args){
int[]数组=新的int[]{1,4,2,6,4,5,10,8,7,11};
系统输出println(nPeaks(array,2));
}
静态int npeak(int[]数组,int范围){
//检查特殊情况
if(数组==null){
返回0;
}
int结果=0,l,r;
//检查主体
for(int i=0;i 对于(int j=l;j),如果您试图访问arr[len]
和arr[len+1]
,它将抛出ArrayIndexOutOfBoundsException
。感谢您的回复,但我已经知道,并且我还说我无法解决此问题,需要一些帮助,您可能在if(I==0)的第一个if中有错误{< /代码>,似乎不应该在那里,如果它需要在那里,那么也许上面的循环没有,你只会从循环中得到一个迭代。我想知道我在这方面缺少什么。除了条件之外。我需要考虑什么其他的场景来解决这个问题。@ NESPowerGlove…如果条件是第一个EL。因为我不需要把这个元素和以前的元素做比较,因为它已经有了。我知道了。请阅读评论。我想知道要解决这个问题或解决这个问题的方法要考虑不同的情况。re@Victor那么你应该问这个问题,并发布你知道问题发生的那一行。请相应地编辑你的问题。阅读代码后的第二句话。你会知道我知道我为什么要面对这个问题,但想知道条件是否完全覆盖。抱歉,如果我把你弄糊涂了。这不是问题所在正确的解决方案。考虑阵列中的情况。当arr[i]=6,6>2和4是它的两个左邻域,6>4和5是它的右邻域,同样对于10和11,它没有右元素,所以我只比较左元素8,7,所以它满足条件,所以它也计数。所以结果应该是3。我很困惑。结果是3。它发现:4(前4),6和10。啊,我想我现在明白了…范围是它大于多少个邻居!明白了。很容易修复。是的。因为6,10,11是各自范围内的峰值。它们在两个左邻居和两个右邻居中最大(其中2是范围)对于11,只考虑左边的2个元素。好的,现在它应该工作。我把PrtLn放在那里进行调试。
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;
}
}