【问题标题】:Java return symmetric pairs from a 2D arrayJava从二维数组返回对称对
【发布时间】:2022-01-10 07:39:11
【问题描述】:

如果我有一个二维数组:

input[][] = { {"A", "B"}, {"C", "D"}, {"B", "A"}, {"C", "E"} }

我想要一个返回的算法

{("A", "B")} or {("B", "A")}

我知道有一个使用 HashMap 的解决方案,但我想在没有的情况下解决这个问题。它不需要是最有效的解决方案。我想在 O(n log n) 时间内实现它,所以我不想使用 HashMap。我正在考虑对输入数组进行排序并比较元素,但我不知道如何实现它。谁能提供一些帮助?

【问题讨论】:

  • 使用HashMap 的解决方案可以是O(n)。不要忽视那个......
  • 数组是否保证唯一?即可以输入{ {"A", "B"}, {"C", "D"}, {"A", "B"}, {"C", "E"} }{"A", "B"} 出现两次)?

标签: java arrays sorting


【解决方案1】:

蛮力

有蛮力方法:对于每一对,看看它的反面是否也存在。所以当你有(A,B)时,看看你是否能找到(B,A)(在你的例子中你可以)。下次你有 (C, D) 时,看看你是否能找到 (D, C)(这次你不能)。使用嵌套循环。在外循环中遍历这些对。在内部循环中再次遍历这些对。如果内循环中的那对与外循环中的相反,则打印这两对。

该方法的时间复杂度为 O(n ^ 2)(可能很明显)。

更高效:首先对对进行排序

在开始之前对对进行排序将允许您对反向对使用二进制搜索。按第一个成员排序,然后按第二个成员排序。在您的示例中,排序顺序为

(A, B), (B, A), (C, D), (C, E)

再次遍历对。得到 (A, B) 后,使用二分查找 (B, A)。当你得到 (C, D) 时,搜索 (D, C)。我应该按排序顺序排在 (C, E) 之后,因为那里什么都没有,所以找不到。

后一种方法的时间复杂度应该是 O(n log n)。

【讨论】:

    【解决方案2】:

    这是一种似乎可行的方法。它不需要任何排序。

    String[][] input = { {"A", "B"}, {"C", "D"}, {"B", "A"}, {"C", "E"} };
    
    • 首先,将串联的数组项复制到一个集合中。
    • 然后遍历数组,执行反向连接并查看集合是否包含该字符串。
    • 如果是这样,删除两个连接的字符串并打印数组。
    Set<String> set = new HashSet<>();
    for (String[] arr : input) {
        set.add(arr[0]+arr[1]);
    }
    for(String[] arr : input) {
        String item1 = arr[1] + arr[0];
        String item2 = arr[0] + arr[1];
        if (set.contains(item1)) {
            set.remove(item1);
            set.remove(item2);
            System.out.println(Arrays.toString(arr));
        }
    }
    

    打印

    [A, B]
    

    上述替代方案是放弃串联并使用Arrays.equals(),尤其是对于较大的数组。在这种情况下,我认为Arrays.equals() 是矫枉过正。并且代替打印,数组可以保存在另一个数据结构中。

    【讨论】:

      【解决方案3】:

      通过哈希集

      static String[] findSymmetricPairByHashSet(String[][] input) {
          record Entry(String a, String b) {}
          Set<Entry> set = new HashSet<>();
          for (String[] a : input) {
              Entry p = new Entry(a[1], a[0]);
              if (set.contains(p))
                  return new String[] {p.a, p.b};
              set.add(new Entry(a[0], a[1]));
          }
          return null;
      }
      

      按树集

      static String[] findSymmetricPairByTreeSet(String[][] input) {
          Set<String[]> set = new TreeSet<>(Arrays::compare);
          for (String[] a : input) {
              if (set.contains(a))
                  return a;
              set.add(new String[] {a[1], a[0]});
          }
          return null;
      }
      

      按排序

      static String[] findSymmetricPairBySort(String[][] input) {
          Arrays.sort(input, Arrays::compare);
          for (String[] a : input)
              if (Arrays.binarySearch(input, new String[] {a[1], a[0]},
                  Arrays::compare) >= 0)
                  return a;
          return null;
      }
      

      测试:

      public static void main(String[] args) throws IOException {
          String[][] input = {{"A", "B"}, {"C", "D"}, {"B", "A"}, {"C", "E"}};
          System.out.println(Arrays.toString(findSymmetricPairByHashSet(input)));
          System.out.println(Arrays.toString(findSymmetricPairByTreeSet(input)));
          System.out.println(Arrays.toString(findSymmetricPairBySort(input)));
      }
      

      输出:

      [A, B]
      [B, A]
      [A, B]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-03-06
        • 2010-09-28
        • 2012-01-26
        • 2021-04-19
        • 2011-02-12
        • 1970-01-01
        • 2013-09-02
        相关资源
        最近更新 更多