【问题标题】:Adding an integer to a sorted ArrayList at the correct index在正确的索引处将整数添加到已排序的 ArrayList
【发布时间】:2020-05-12 03:37:49
【问题描述】:

假设我有一个像 thisArrayList<Integer> arr = Arrays.asList(1, 2, 3, 5, 6) 这样的排序列表(按升序排列)。列表中不会有重复项。

我想在正确的索引处添加一个整数,以便在我添加元素后数组仍然排序,如下所示:arr.add(4) // now arr = {1, 2, 3, 4, 5, 6}

我如何优雅地实现这一点没有在我使用Collections.sort(arr) 或其他东西添加元素之后进行排序。

我正在寻找一种比我目前拥有的更好/更优雅的解决方案(我什至不知道它是否适用于所有情况,哈哈):

int n = 4 // number I want to add to the list
boolean added = false;

for(int i < 0; i < arr.size(); i++) {
   if(n < arr.get(i)) {
     arr.add(i, n)
     added = true;
     break;
   }
}

if(added == false) {
  arr.add(n)
}

提前感谢您的帮助!

【问题讨论】:

  • 列表会有重复吗?
  • @RobbyCornelissen 对不起,我忘了提。列表中没有重复项。

标签: java sorting arraylist


【解决方案1】:

您现在进行的线性搜索是 O(n),加上对 add() 的调用的 O(n)。

您可以使用Collections.binarySearch() 在 O(log n) 时间内找到插入点,然后像现在一样调用add()。由于 O(log n + n) = O(n),因此总体复杂度仍然是 O(n),但它会稍微快一些,并且代码会短一些。

int i = Collections.binarySearch(arr, n);

// `n` not found. Retrieve the insertion point from the return value.
if (i < 0) {
    i = -i - 1;
}

arr.add(i, n);

【讨论】:

  • 在我最诚实的意见中,这个答案的优势不在于它更高效(它适用于非常大的列表),而是代码更优雅和简洁。跨度>
【解决方案2】:

使用TreeSet 作为中介。 TreeSet 是一个二叉搜索树,当你遍历它时,你会得到按排序顺序排列的元素。

Set<String> set = new TreeSet<Integer>(arr);
set.add(n);
arr = new ArrayList<Integer>(set);

【讨论】:

    【解决方案3】:

    您将使用二进制搜索来确定插入位置。

    要么封装内置的Collections.binarySearch 方法:

    // insert v into list if not present, maintaining order
    // return whether list was updated
    static boolean insert(List<Integer> list, int v)
    {
        int pos = Collections.binarySearch(list, v);
        if(pos >= 0)
            return false;
    
        pos = -pos - 1;
        list.add(pos, v);
        return true;
    }
    

    或者只是为了兴趣,自己动手:

    static boolean insert(List<Integer> list, int v)
    {
        int low = 0; 
        int high = list.size();
        while(low < high)
        {
            int mid = low + (high-low)/2;
            if(list.get(mid) < v)
                low = mid+1;
            else if(list.get(mid) > v)
                high = mid;
            else
                return false;               
        }
        list.add(low, v);
        return true;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-15
      • 1970-01-01
      • 1970-01-01
      • 2014-06-10
      • 2014-03-23
      • 2013-03-25
      • 1970-01-01
      • 2018-05-22
      相关资源
      最近更新 更多