我有两个单一链接的整数列表。其中一个是另一个的子集(数字的顺序不同)。找到第一个列表包含的数字而第二个列表没有的最佳方法(关于性能)是什么?
我的想法是首先对它们进行排序(使用合并排序),然后逐个元素地进行比较。
因此,它需要O(nlogn+mlogm+n)
,但应该存在更好的O(n)
解决方案。
答案 0 :(得分:2)
这是时间和空间的O(n)解决方案。
<强>逻辑强>
假设原始链接列表的大小为N ,我们将其称为LL1
,将第二个链接列表称为LL2
。
=&gt; 准备一个大小为N的Hasmap
,key
将是numbers
和LL1
中的value
频率为LL2
HashMap<Integer,Integer> map= new HashMap<Integer,Integer>();
=&gt; 开始遍历LL1
并将所有数字的频率设置为0,当迭代LL1
中的所有值时,您有HashMap
中频率= 0
map.put(key, 0);
=&gt; 现在开始循环浏览LL2
,使用它们作为键选择数字并将值增加1
。
到所有时候LL2
中的值会被迭代,LL1
和LL1
中HashMap
frequency > 0
内的所有公共数字都会 map.put(key, map.get(key) + 1);
hasmap
=&gt; 现在开始遍历value = 0
,搜索key
,找到后,打印LL1
,因为此号码仅出现在{{1}而不是LL2
for (map.Entry<Integer,Integer> entry : map.entrySet())
{
if(entry.getValue() == 0)
System.out.println(entry.getKey());//This is a loner
}
2次迭代和O(n)内存,O(n)时间。
答案 1 :(得分:1)
您可以将它们放在不同的地图中,然后进行比较。放入地图应该是2个单独的m&amp; n并查找地图的时间是1。
答案 2 :(得分:0)
HashSet是在这种情况下使用的最佳数据结构。 使用此代码,您可以在O(n)中获得结果。 如果您有更多条件,请告诉我,我可以据此提出建议。
public class LinkedList {
private ListNode head;
public ListNode getHead() {
return head;
}
}
public class ListNode {
public int value;
public ListNode next;
ListNode(int value) {
this.value = value;
}
}
public class UtilClass{
public static int checkLists(LinkedList list1, LinkedList list){
ListNode head = myList2.getHead();
HashSet<Integer> hashSet = new HashSet<Integer>();
while(head!=null){
hashSet.add(head.value);
head = head.next;
}
head = myList.getHead();
while(head!=null){
boolean b = hashSet.add(head.value);
if(b == true) return head.value;
head = head.next;
}
return -1111;
}
}
答案 3 :(得分:0)
您可以使用removeAll方法。您所要做的就是创建一个接受两个列表的方法,一个是原始列表,另一个是子列表,然后返回缺少元素的列表:
List getMissing(List original, List sub){
original.removeAll(sub);
return original;
}
虽然这是以二次方式运行的。
如果你真的想强制它以线性时间O(n)运行,那么你必须编写自定义类来包装你的输入,这样对于每个输入,都有一个标志来监视它是否已经存在添加到子列表中。您还可以设计一个类,以便在监视两个列表的内容时促进元素的添加和删除。
答案 4 :(得分:0)
设N = m + n。
所以 O(N.log N)。
由于列表没有订购,任何加速都包括排序和成本等。所以O(N.log N)没问题。
如果您想要 O(N), 可以按照以下方式执行此操作(简化,使用正数):
BitSet present = new BitSet(Integer.MAX_VALUE);
for (int value : sublist)
present.set(value);
for (int value : list)
if (!present.isSet(value)) {
System.out.println("Missing: " + value);
break;
}
这会使记忆与时间交换。请注意,这个答案可能不被接受,因为内存 2 MAX_VALUE ,这也是初始化/清算成本时间。
可能的&lt; O(N log N)解决方案
最聪明的答案可能是(准)排序合作两个列表。在排序期间检测缺失的元素。就像挑选一个偶然的“中位数”元素和转移指数以分割列表,分裂和征服一样。
如果列表大小相差1
然后你只需要为每个列表计算总和,差异是缺失值:O(N)。 适用于溢出。