【问题标题】:Sort list based on first occurance of elements根据第一次出现的元素对列表进行排序
【发布时间】:2021-12-14 20:15:20
【问题描述】:

我有一个带有一组值的 Java List<Integer>,例如:

[0, 5, 2, 1, 3, 2, 6, 1, 1, 0, 10]

我想按每个元素的第一次出现对列表进行排序,新排序的列表如下:

[0, 0, 5, 2, 2, 1, 1, 1, 3, 6, 10]

我正在处理的 List 最多有 400-500 个元素,因此首选轻量级的东西,但我不太想办法。

【问题讨论】:

    标签: java list sorting


    【解决方案1】:

    您可以直接使用indexOf的结果进行排序(返回列表中元素的第一个索引)。

    List<Integer> list = Arrays.asList(0, 5, 2, 1, 3, 2, 6, 1, 1, 0, 10);
    list.sort(Comparator.comparingInt(list::indexOf));
    System.out.println(list);
    

    Demo

    【讨论】:

    • 虽然复杂度为 O(n^2 log(n)),对吧?
    • @Stef 是的,但这对于 400-500 个元素来说应该不是问题。它可以通过使用Map 来存储每个元素的第一次出现进行优化。
    • 公平点,但仍然比二次复杂,对于可能是线性的东西,至少你应该在你的答案中用粗体字母警告。
    【解决方案2】:

    我认为使用 LinkedHashMap 有更简单的解决方案,它会记住放置顺序:

        List<Integer> source = Arrays.asList(0, 5, 2, 1, 3, 2, 6, 1, 1, 0, 10);
        List<Integer> target = new ArrayList<>();
    
        Map<Integer, Integer> map = new LinkedHashMap<>();
        source.forEach(number -> map.merge(number, 1, Integer::sum));
    
        map.forEach((key, value) -> {
            for (int i = 0; i < value; i++) {
                target.add(key);
            }
        });
    
        System.out.println(target);
    

    【讨论】:

      【解决方案3】:

      您需要 2 个数据结构:

      • 用于存储数字出现次数的地图
      • 要记住它们发生的顺序的列表

      这段代码做你想做的事:

      String in = "0, 5, 2, 1, 3, 2, 6, 1, 1, 0, 10";
      String[] split = in.split(", ");
      List<Integer> lstIn = Arrays.stream(split).map(Integer::parseInt).collect(Collectors.toList());
      Map<Integer, Integer> theMap = new HashMap<>();
      List<Integer> listOccurence = new LinkedList<>();
      
      for(Integer i:lstIn) {
          theMap.compute(i, (k,v)->v==null?1:v+1);
          if(!listOccurence.contains(i)) {
              listOccurence.add(i);
          }
      }
      List<Integer> out = new LinkedList<>();
      for(Integer i:listOccurence) {
          Integer count = theMap.get(i);
          for(int j=0;j<count;j++) {
              out.add(i);
          }
      }
      System.out.println(out);
      

      打印出来:

      [0, 0, 5, 2, 2, 1, 1, 1, 3, 6, 10]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-05-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-12
        相关资源
        最近更新 更多