【问题标题】:Algorithm to verify if a two-dimensional array has two equals rows验证二维数组是否有两个相等行的算法
【发布时间】:2016-06-13 13:24:23
【问题描述】:

定义一个方法,在该方法中,给定一个二维数组,计算它是否至少有两个相同的行

我试图想出一个算法来做到这一点,但我没有走得太远。这是我得到的:

public static boolean righeUguali(int[][] a){
    boolean rUguali=false;

    for(int i=0; i<a.length; i++)
        for(int j=0; i<a[i].length; j++)
            if(Arrays.equals(a[i],a[j]))
                rUguali = true;
    return rUguali;

你能帮我修复这个代码吗?

【问题讨论】:

  • 你想用那个算法做什么,你的代码有什么问题?
  • 它不起作用。它显然有问题,但我无法弄清楚它是什么。如果 2 行相同,它应该返回 true
  • 你在第二个中使用 i
  • 您还需要将j=0 更改为j=i+1;否则你会自己检查数组。

标签: java arrays algorithm


【解决方案1】:
  • 您需要确保没有将行与自身进行比较。您可以确保以 i+1 开头的 j
  • 两个循环都需要遍历行
  • 两行中的第一个不能是最后一个,否则就没有第二行可以与之比较了。
  • 优化:发现两个相等的行就可以终止

这里是修改后的代码:

public static boolean righeUguali(int[][] a){
    for(int i=0; i<a.length-1; i++)
        for(int j=i+1; i<a.length; j++)
            if(Arrays.equals(a[i],a[j]))
                return true;
    return false;
}

【讨论】:

  • 特别感谢优化
  • @Daniele:仍然是 O(n²)*.*:如果速度是问题:您可以使用 HashSet 获得 **O(n)
  • 我认为这样的小方法不是问题。但我仍然喜欢发现改进代码的新方法
【解决方案2】:

我会这样做:

int[][] array = { { 1, 2, 3, 4, 5, 6 },
            { 7, 6, 8, 3 }, 
            { 1, 2, 3, 4 },
            { 1, 2, 3, 9, 5, 6, 32, 3125423 },
            { 8, 3 }, 
            { 1, 2, 3, 4, 5, 6 } };//same as first row
    external: for (int i = 0; i < array.length; i++) {
        for (int j = i + 1; j < array.length; j++) {
            if (Arrays.equals(array[i], array[j])) {
                System.out.println("Row: " + i + " is the same as row: " + j+" (warning! 0 oriented!)" );
                break external;
            }
        }
    }

如您所见,array[] 是非常随机的,但第一行(第 0 行)与最后一行(第 5 行)相同,所以我接下来要做的就是在每次循环中循环遍历数组一次通过数组的剩余行。然后我比较数组来检查它们是否相同。如您所见,代码打印出一条消息,然后终止(停止外部循环)

这是基于一个简单的排序算法。

EDIT #1 正如@4castle 在 cmets 中指出的那样,在方法的上下文中,break 语句不是必需的,可以用 return 代替。

【讨论】:

  • 由于这是在一个方法中,您可以使用return 来终止循环而不是中断命名循环。
  • @4castle 确实,但我并没有真正针对一种方法,因为实际上这段代码是从我的一个项目中提取的。无论如何,在我的帖子中提到这一点:) 谢谢!
  • 非常感谢!它解决了我的问题
  • @Daniele 我很高兴能帮上忙! :-)
【解决方案3】:

通过应用near-duplicate question 中最简单的答案:

public static boolean righeUguali(int[][] a) {
    for(int i = 0; i < a.length; i++)
        for(int j = i + 1; j < a.length; j++)
            if(Arrays.equals(a[i], a[j]))
                return true;
    return false;
}

您的算法正在破坏,因为j 似乎在那里迭代嵌套数组。这不是必需的,因为Arrays.equals 将遍历嵌套数组。相反,将其用作第二个迭代器,以查找是否有任何其他元素与i 指定的当前元素匹配。

如果您想要更好的性能,重复问题有更快的解决方案。

【讨论】:

    【解决方案4】:

    还没有人提到更快的方法是对顶级数组进行排序,然后查找两个相同的相邻行。如果数组是 m*n,这将需要 O(mn log n) 时间,而所有现有解决方案都需要 O(mn^2) 时间。

    当然,如果您不能对行重新排序,那么您需要先制作数组的副本 - 但除非您的数组占用 > 50% 的可用 RAM,否则创建副本然后对其行进行排序仍将比现有解决方案快得多。

    【讨论】:

    • 不客气 :) 排序是 CS 中在意想不到的地方非常有用的东西之一!
    猜你喜欢
    • 1970-01-01
    • 2020-01-02
    • 1970-01-01
    • 1970-01-01
    • 2017-08-26
    • 1970-01-01
    • 2017-11-01
    • 1970-01-01
    • 2019-07-04
    相关资源
    最近更新 更多