Algorithm 链表-从指定范围中删除数字

Algorithm 链表-从指定范围中删除数字,algorithm,Algorithm,我有一个包含从0到1的数字的链表,我的任务是从该列表中删除给定范围(x,y)中的数字。你知道如何以合理的复杂度解决这个问题吗?如果你仔细想想,linkedlist没有方法获取索引。你只能从头开始,一直到尾,反之亦然。这个问题的复杂性是O(n)让我们先考虑一下链接列表的结构。让我们看一看下图: (双重)链表中的每个元素都有一个指向下一个(和上一个)元素的指针。Java类LinkedList例如是一个双链接列表 在这样的列表中,无法直接访问“给我元素B的索引”。我们只有一个head引用(指向列表的

我有一个包含从0到1的数字的链表,我的任务是从该列表中删除给定范围(x,y)中的数字。你知道如何以合理的复杂度解决这个问题吗?

如果你仔细想想,linkedlist没有方法获取索引。你只能从头开始,一直到尾,反之亦然。这个问题的复杂性是O(n)

让我们先考虑一下
链接列表的结构。让我们看一看下图:

(双重)链表中的每个元素都有一个指向下一个(和上一个)元素的指针。Java类
LinkedList
例如是一个双链接列表

在这样的列表中,无法直接访问“给我元素B的索引”。我们只有一个
head
引用(指向列表的开头)和一个
tail
引用(指向末尾)。要查找元素B,我们需要从
(或
)开始,沿着元素的
下一个
(或
上一个
)指针,完全遍历整个列表,直到找到元素B


因此,回到您的问题,没有有效的方法从
链接列表中删除
范围(x,y)
的元素。这只能在排序结构(例如
PriorityQueue
或排序的
ArrayList
二进制搜索生成
O(log(n)
)或直接访问元素(例如
哈希集
)的结构中有效地完成


下面是Java中的一个代码片段,它解决了
LinkedList
的任务,但是,如上所述,它效率低下,运行时间为
O(n)
(我们需要查看每个元素,以找出需要删除哪些元素):

LinkedList=。。。
//包含下界
int lowerBound=。。。
//排他上界
int上限=。。。
ListIterator listIter=list.ListIterator();
while(listIter.hasNext()){
int value=listIter.next();
//检查该值是否在边界内
如果(值>=下限| |值<上限){
//使用迭代器从列表中删除元素
//这可以防止ConcurrentModificationException
listIter.remove();
}
}

>如果可能的话,更适合的数据结构将是排序的,或者甚至是<代码> SET/COD>变型,如<代码> HASSETSE/COD>。您有任何尝试或代码吗?是否想用java或C++的特定语言解决这个问题?如果是,请也添加相应的标签。不,我不必用任何特定语言解决这个问题。我在寻找一个纯算法:)所以我必须检查所有元素,对吗?您确定没有更快的算法使用特定于linkedlist的属性吗?如果我听起来像个傻瓜,我很抱歉,但我仍在学习。:)如果任务不限于LinkedList,我将使用其他数据结构。如果任务只是在排序列表中查找下限和上限的索引。您可以在
log(n)
中执行此操作,感谢您提供详尽的答案。这是我大学算法课程的一项任务。这个答案对我来说太明显了,所以我开始思考是否有更快的解决方案。我知道实际上没有。是的,这种问题肯定不是为
LinkedList
设计的。它的优点是您可以轻松地从内部删除或添加元素。还有一个优点是,元素本身可以任意放置在内存中,例如,所有元素的内存不需要连接到数组中。
LinkedList<Integer> list = ...

// Inclusive lower bound
int lowerBound = ...
// Exclusive upper bound
int upperBound = ...

ListIterator<Integer> listIter = list.listIterator();
while (listIter.hasNext()) {
    int value = listIter.next();

    // Check if the value is inside bounds
    if (value >= lowerBound || value < upperBound) {
        // Remove the element from the list using the iterator
        // which prevents ConcurrentModificationException
        listIter.remove();
    }
}