【问题标题】:How can i replace duplicate integers in an ArrayList with the missing integers如何用缺失的整数替换 ArrayList 中的重复整数
【发布时间】:2021-03-08 16:08:58
【问题描述】:

我想用缺失的整数替换大小为 n 的 ArrayList 中的重复整数。例如:

import java.util.ArrayList;

public class Main {

  public static void main(String[] args) {

    ArrayList<Integer> myNumbers = new ArrayList<Integer>();
    myNumbers.add(1);
    myNumbers.add(2);
    myNumbers.add(1);
    myNumbers.add(3);
    myNumbers.add(1);
   
  }
}

arraylist 有 5 个元素,所以它应该包含数字 1 ,2 ,3 ,4, 5 (不按特定顺序)。 (如果大小为 99,则应该有 1 到 99 之间的数字,不能重复)。

它应该从 [1,2,1,3,1] 到 [1,2,4,3,5] 或 [1,2,5,3,4]。它必须适用于任何大小,并且可以有多个重复项。

目前我只能使用一个集合来消除重复项,但我不知道用缺失的元素替换它们。

【问题讨论】:

    标签: java arraylist duplicates integer


    【解决方案1】:
    1. 先找出缺失值
    2. 遍历您的列表并检查当前值是否重复。如果为 true,则替换为缺失值之一

    假设您使用的是 java 8 或更高版本,下面的内容可能是一个起点:

    import java.util.ArrayList;
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Set;
    import java.util.stream.Collectors;
    import java.util.stream.IntStream;
    
    public class Test {
    
        public static void main(String[] args) {
            List<Integer> myNumbers = new ArrayList<>();
            myNumbers.add(1);
            myNumbers.add(2);
            myNumbers.add(1);
            myNumbers.add(3);
            myNumbers.add(1);
            System.out.println("original: " + myNumbers);
            List<Integer> missing = IntStream.rangeClosed(1,myNumbers.size())
                    .filter(i -> !myNumbers.contains(i))
                    .boxed().collect(Collectors.toList());
            System.out.println("missing: " + missing);
    
            Set<Integer> unique = new HashSet<>();
            Iterator<Integer> misIterator = missing.iterator();
            for(int i = 0; i < myNumbers.size(); i++){
                if(!unique.add(myNumbers.get(i))){
                    myNumbers.set(i, misIterator.next());
                }
            }
            System.out.println("modified" + myNumbers);
        }
    }
    

    【讨论】:

      【解决方案2】:

      这是我对问题/问题陈述的理解:

      • 您的输入是一个可能重复的数字 1 - n 的列表,其中 n 永远不会大于列表的大小。
      • 迭代列表时数字的第一个实例(非重复)应保留在其当前索引处。
      • 在迭代列表时找到的数字的每个后续副本都应替换为“缺失集”中的数字。
      • “缺失集”包含 1 - n 的所有数字,其中 n 是删除了现有集(从输入列表中)后的列表大小。
      • 最终结果列表应包含所有数字 1 - listSize 且没有重复项,并且任何数字的第一个实例(从列表的开头进行迭代)与输入列表位于同一索引处。

      如果上面的陈述听起来正确,这是一种方法(尽管可能有一种更优化的方法):

      import java.util.ArrayList;
      import java.util.HashSet;
      import java.util.Random;
      import java.util.Set;
      import java.util.stream.Collectors;
      import java.util.stream.IntStream;
      
      public class ReplaceDuplicateIntegersRunner {
          private static ArrayList<Integer> sampleIntegerList = new ArrayList<>();
      
          public static void main(String[] args) {
              addRandomIntegersToList(3,7);
              System.out.println("List Before: " + sampleIntegerList);
              replaceDuplicatesWithContinuedCount();
              System.out.println("List After: " + sampleIntegerList);
      
          }
      
          public static void addRandomIntegersToList(Integer maxValue, Integer numOfIntegers) {
              Random randomGen = new Random();
              for (int num = 0; num < numOfIntegers; num++) {
                  sampleIntegerList.add(1 + randomGen.nextInt(maxValue));
              }
          }
      
          public static void replaceDuplicatesWithContinuedCount() {
              // generate a set of integers 1 - length of sampleIntegerList
              Set<Integer> integerSetToAdd = IntStream.rangeClosed(1, sampleIntegerList.size())
                      .boxed().collect(Collectors.toSet());
              // remove the integers which already exist in the target sample list
              integerSetToAdd.removeAll(new HashSet<>(sampleIntegerList));
              ArrayList<Integer> integersToReplaceDuplicates = new ArrayList<>();
              integersToReplaceDuplicates.addAll(integerSetToAdd);
              int indexOfIntegersToAdd = 0;
              HashSet<Integer> duplicatesInList = new HashSet<>();
              for (int index = 0; index < sampleIntegerList.size(); index++) {
                  // if our duplicate set doesn't already have this number, we don't have a duplicate, add it to the set
                  // and continue on
                  Integer integerAtIndex = sampleIntegerList.get(index);
                  if (duplicatesInList.contains(integerAtIndex) == false) {
                      duplicatesInList.add(integerAtIndex);
                  } else {
                      // otherwise we've found a duplicate and need to replace it with the next one to replace
                      sampleIntegerList.set(index, integersToReplaceDuplicates.get(indexOfIntegersToAdd));
                      indexOfIntegersToAdd++;
                  }
              }
          }
      }
      

      一些带有从上面传入的参数的示例输出:

      列出之前:[3、2、3、3、1、1、1] 列表之后:[3, 2, 4, 5, 1, 6, 7]

      列出之前:[2, 3, 2, 2, 3, 2, 1] 列表之后:[2, 3, 4, 5, 6, 7, 1]

      【讨论】:

        【解决方案3】:

        如果您想获得一系列数字不是按特定顺序,您可以创建它并替换旧的:

        List<Integer> list = IntStream
                // from 1 to 5 inclusive
                .rangeClosed(1, 5)
                // Stream<Integer>
                .boxed()
                .collect(Collectors.toList());
        
        // random order
        Collections.shuffle(list);
        
        System.out.println(list); // [2, 4, 3, 1, 5]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-03
          • 2013-10-30
          • 1970-01-01
          • 1970-01-01
          • 2015-07-20
          • 2020-07-13
          相关资源
          最近更新 更多