检测本地最小值和最大值,java

时间:2010-10-29 10:19:54

标签: java algorithm comparison

给出任何整数序列,如 23 7 13 4 8 6 。我想通过以下规则检测局部最小值和最大值:

  • 当以下数字更大时,序列中的第一个数字是局部最小值
  • 当前一个数字更大时,序列中的最后一个数字是局部最小值
  • 当序列中的数字小于前一个和后面的数字
  • 时,它是一个局部最小值

我可以使用方法 hasNextInt getNextInt

目前我正在考虑这个算法。但我不确定我是否理解逻辑。首先,我构建一个元组并比较它的数字。例如。我比较23和7. 7是当地最小值。那我该怎么办?建立三重?但是那个数字有三倍,23 7 13或13 4 8?我不确定。

有什么想法吗?

更新

假设我们将左邻居和数字存储在三个数字的中间:

left    middle    current

0        0         23

23       0         7

23       7         13 <- you have a triple, compare => minimum 7

那会怎么样?将vars设置为0并从下一个数字4开始?或者在左边存储7,在中间存储13以使4为当前?

更新(此代码似乎有效):

    int left   = 0;
    int center = 0;
    while(hasNextInt()){
        int current = getNextInt();

        if((left != 0) && (center != 0)){
            if(current > center && center < left){
                System.out.println("Min: "+center);
                left = center; center = current;
            }else{
                left = center; center = current;
            }
        }else if((left != 0) && (center == 0)){
            if(left < current){
                System.out.println("Min: "+left);
                center = current;
            }else{
                center = current;
            }
        }else if((left == 0) && (center == 0)){
            left = current;
        }
    }

    if(left > center){
        System.out.println("Min: "+center);
    }

感谢您的帮助!

4 个答案:

答案 0 :(得分:3)

这是一个建议:

private void findMin() {

    int count = 0; // To handle special case of singleton list

    int left  = Integer.MAX_VALUE;
    int mid   = Integer.MAX_VALUE;
    int right = Integer.MAX_VALUE;

    while (hasNextInt()) {
        count++;
        left = mid;
        mid = right;
        right = getNextInt();

        if (right > mid && mid < left)
            System.out.println("local min: " + mid);
    }

    if (count > 1 && right < mid)
        System.out.println("local min: " + right);
}

(Ideone演示可用here。)

答案 1 :(得分:2)

你在那里看起来是一个好的开始。

但是,仅查看元组是不够的,因为您必须查看三个数字才能检测到局部最小值 - 因此您必须扩展算法。

要了解如何执行此操作,请尝试在纸上进行简单示例。你会如何手动找到当地的最小值?你可以在你的程序中做类似的事情吗?

随意发布您的程序的更新版本(通过编辑问题,将新代码添加到底部),如果您仍然卡住,我们可以提供帮助。

回答您的修改:

  

那会怎么样?设置变量   到0并从下一个数字4开始?   或者在左边存储7个,在中间存储13个   有4个当前的?

你不能只把一切都设为0;你仍然需要你的三元组的最后两个数字来开始下一个三元组,因为你的三元组表现就像一个窗口滑过数字列表(这通常被称为“滑动窗口”技术,因为许多算法使用它)。

您可以手动将数字复制到新变量中。

为了更加优雅,您可以在单独的“Triplet”类中实现此功能。要考虑的想法:该类可以检查最小值,并允许您添加新号码,自动“推出”最旧的号码。

答案 2 :(得分:1)

使用两个布尔值跟踪您之前是否增加或减少了。当您读取数组中的下一个数字时,再次检查并比较4个布尔值:

local_minimum = previously_decreased && just_increased;
local_maximum = previously_increased && just_decreased;

然后只存储 - &gt;以前继续。

一开始,两个previous_布尔值都应该设置为true。最后,您将需要另一个循环设置,将just_booleans设置为true。

显然,这些增加/减少的布尔值是严格的,所以相等的值会使两个布尔值都为假。

希望有所帮助。

答案 3 :(得分:1)

按照定义,在序列中间某处考虑三元组:

... A, B, C,  ...

显然是B局部最小值iff(当且仅当时):A-B > 0 && B-C <0

否则B局部最大值iff:A-B < 0 && B-C >0

没什么特别的

如果你实现了这个逻辑,并遍历列表,专门处理末尾的案例,你应该能够找到O(n)中的所有局部最优值。