【问题标题】:Finding the lowest unused unique id in a list查找列表中最低的未使用唯一 ID
【发布时间】:2011-03-27 06:10:20
【问题描述】:

假设有一个列表。列表中的每个项目都有一个唯一的 ID。

List [5, 2, 4, 3, 1]

当我从这个列表中删除一个项目时,该项目的唯一 ID 会随之而来。

List [5, 2, 3, 1]

现在假设我想在列表中添加另一个项目,并为其指定最低的唯一 ID。

向列表中添加新项目时获得最低唯一 ID 的最简单方法是什么?

这里有一个限制:如果我在删除一个项目时没有重新分配另一个项目的唯一 ID,我会更喜欢它。

我意识到,如果我在删除 4 时将唯一 ID 5 重新分配给唯一 ID 4,将很容易找到唯一 ID。然后我可以获得列表 (5) 的长度并创建具有唯一 ID 的新项目用那个号码。

那么还有另一种方法,不涉及遍历整个列表?

编辑:

语言是java,但我想我正在寻找一个通用算法。

【问题讨论】:

  • 您使用什么语言?另外:在这种情况下,您对“uniqueidentifier”标签的使用可能不正确。您能看看是否有其他标签可以更好地为您服务吗?
  • 优先队列是一个很好的数据结构,无论如何都可以学习,并且是解决问题的好方法。但是,我想知道,如果只是一个简单的列表就可以了。您需要最低而不只是确保重复使用漏洞,是否有特殊原因?

标签: algorithm list


【解决方案1】:

它相当于一个搜索,只是这次你搜索一个丢失的数字。如果您的 ID 是排序整数,您可以从下到上开始检查两个 ID 之间的空格是否为 1。 如果您知道列表中有多少项目及其排序,则可以实现二进制搜索。

【讨论】:

    【解决方案2】:

    如果不遍历列表,我认为您无法做到这一点。

    当你说

    '现在说我想添加另一个项目 清单,并给它最少 最高的唯一标识。 '

    我假设您的意思是要分配尚未在其他地方使用过的最低可用 ID。

    你可以这样做:

    private int GetLowestFreeID(List list){
        for (int idx = 0; idx < list.Length; ++i){
            if ( list[idx] == idx ) continue;
            else return idx;
        }
    }
    

    这将返回最低的空闲索引。

    这假设您的列表已排序,并且使用 C#,但您明白了。

    【讨论】:

      【解决方案3】:

      一种简单快捷的方法是将已删除的 id 放入优先级队列中,然后在插入新的 id 时从那里选择下一个 id(或在队列位于时使用第一个列表的 size() + 1 作为 id空的)。但是,这将需要另一个列表。

      【讨论】:

      • 很好的答案,欢迎堆栈溢出! “优先队列”是指堆吗?
      • 谢谢!是的,一个堆,或者任何排序的东西,允许在 O(1) 中找到最低的 id。在 Java 中有一个类 PriorityQueue。
      【解决方案4】:

      您可以维护一个可用 ID 的列表。

      声明一个布尔数组(伪代码):

      boolean register[3];
      register[0] = false;
      register[1] = false;
      register[2] = false;
      

      添加元素时,从寄存器底部循环直到找到false 值。将 false 值设置为 true,将该索引指定为唯一标识符。

      removeObject(index)
      {
          register[index] = false;
      }
      
      getsetLowestIndex()
      {
          for(i=0; i<register.size;i++)
          {
            if(register[i]==false)
            {
                 register[i] = true;
                 return i;
            }
          }
      
          // Array is full, increment register size
          register.size = register.size + 1;
          register[register.size] = true;
          return register.size;
      }
      

      删除元素时,只需将索引设置为 false。

      您可以通过使用连续性标记来针对更大的列表进行优化,这样您就不需要循环整个内容。

      这对于索引没有特定顺序的示例最有效,因此您无需先对它们进行排序。

      【讨论】:

        【解决方案5】:

        用于执行此操作的数据结构是只允许唯一值的优先二叉堆。

        【讨论】:

          【解决方案6】:

          如何保持列表排序。而且您可以轻松地将其从一端移除。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-09-24
            • 2013-04-17
            • 2021-01-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-02-06
            • 2018-07-14
            相关资源
            最近更新 更多