我的问题是,是否有可能获得2个未排序的列表,并根据其在第一个列表“ List1”中的顺序获取两个列表的交集。
public static List intersection(List A, List B) {
List outcome = null;
try {
outcome = A.getClass().newInstance();
} catch (Exception e) {};
LinkedList<Integer> temp = new LinkedList<>();
LinkedHashSet<Integer> ALinkedSet = new LinkedHashSet<>(A);
LinkedHashSet<Integer> BLinkedSet = new LinkedHashSet<>(B);
// first filter elements into temp
while (ALinkedSet.size() > 0) {
int v = ALinkedSet.removeFirst();
if (BLinkedSet.contains(v)) {
temp.addLast(v);
}
}
// add filtered values back to L1
while (temp.size() > 0) {
outcome.addLast(temp.removeFirst());
}
return outcome;
}
我正在寻找一种方法来完成这项工作,也许将其转为O(n)。
这是简单的方法。是否有更好的方法将大O变成线性?我很确定至少这是O(n * n)。
public static List Intersection(List A, List B) {
List outcome = null;
try {
tulos = A.getClass().newInstance();
} catch (Exception e) {};
LinkedHashSet<Integer> AHashSet = new LinkedHashSet<>(A);
LinkedHashSet<Integer> BHashSet = new LinkedHashSet<>(B);
for(Integer Aitem : AHashSet){
for(Integer Bitem : BHashSet){
if(Aitem==Bitem) {
outcome.add(Aitem);
}
}
}
return outcome;
}
以下内容是否会线性出现?
public static List Intersection(List A, List B) {
List outcome = null;
try {
tulos = A.getClass().newInstance();
} catch (Exception e) {};
LinkedHashSet<Integer> BHashSet = new LinkedHashSet<>(B);
for(Object Aitem : A) {
if(BHashSet.contains(Aitem) && !outcome.contains(Aitem)){
outcome.add(Aitem);
}
}
return outcome;
}
答案 0 :(得分:1)
更新:由于我们只能使用LinkedHashMaps ...
...并且列表可以重复:
ListEntry
类,该类具有数字和该数字在列表中重复的总次数。因此,如果2出现两次,我们将在LinkedHashMap(LHM)中创建一个new ListEntry(number: 2, count: 2);
; ListEntry
对象的LHM; numberSeen
)中,并更新另一个计数器(intersectionCount
)来跟踪总相交到目前为止看到的数字; numberSeen
和intersectionCount
创建最终列表很简单。运行时复杂度再次为O(m + n),空间复杂度为O(n)。
原始回复:
假设第一个列表的大小为 n ,第二个列表的大小为 m ,这是一种简单直接的解决方案,适用于O(m + n)时间和O(m + n)空间。
Integer
映射到Integer
的哈希映射中。这是为了跟踪列表中的重复项。如果列表中没有重复项,只需使用哈希集; 最后,您的新列表将包含两个列表的交集,按照它们在第一个列表中出现的顺序。
哈希表的总空间= m +新列表的n =。
总时间= m(用于将元素放入哈希图中),n(用于在第一列表上进行迭代)。
因此,O(m + n)时间和O(m + n)空间。
答案 1 :(得分:0)
怎么样:
LinkedHashSet<Integer> intersection = new LinkedHashSet<>(A).retainAll(new HashSet<>(B));
或者在List
中获得输出:
List<Integer> intersection = new ArrayList<> (new LinkedHashSet<>(A).retainAll(new HashSet<>(B)));
实际上,这可能已经足够:
List<Integer> intersection = new ArrayList<> (A).retainAll(new HashSet<>(B));
由于retainAll
的实现调用了传递的contains
的{{1}},因此我们只需要将Collection
转换为B
就可以保持恒定的搜索时间
编辑:
要将建议的解决方案转换为线性时间解决方案,您应该利用HashSet
查找时间:
HashSet