这就是我在做的事:
字符串一=“一些字符串”
String two =“some string”
我想知道字符串一个和两个中的所有字符,它们应该按顺序排列,因为它们在字符串一中
我编写了一个Java程序,通过使用Collections对集合执行set操作 我想知道执行集合运算的复杂性是多项式时间还是线性时间
我的节目在这里
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package careercup.google;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
/**
*
* @author learner
*/
public class CharaterStringsIntersection {
private static final String one = "abcdefgabcfmnx";
private static final String two = "xbcg";
public static void main(String args[]){
List<Character> l_one = new ArrayList<Character>();
List<Character> l_two = new ArrayList<Character>();
for(int i=0; i<one.length(); i++){
l_one.add(one.charAt(i));
}
for(int j=0; j<two.length(); j++){
l_two.add(two.charAt(j));
}
l_one.retainAll(l_two);
Iterator iter = l_one.iterator();
while(iter.hasNext()){
System.out.println(" > " + iter.next());
}
}
}
输出:
run:
> b
> c
> g
> b
> c
> x
答案 0 :(得分:5)
其复杂度为O(N *(N + M)),其中N = one.length()
,M = two.length()
。
它的工作方式如下:对于l_one
的每个字符(其中有N个),它会扫描l_two
(因为l_two
是ArrayList
,扫描是线性,所以需要O(M)步,见[1])并在必要时从l_one
移除项目(从ArrayList
移除需要O(N),见[1]),所以你得到O(N *(N + M))。
您可以使用LinkedList
l_one
将复杂度降低到O(N * M)(因为从LinkedList
删除是O(1),请参阅[2]),以及进一步
使用TreeSet
l_two
将其降低为O(N * log(M))(因为在TreeSet
中搜索需要O(log(M)),参见[3])。< / p>
<强>参考文献:强>
ArrayList
javadoc)LinkedList
javadoc)add
,remove
和contains
)(TreeSet
javadoc)提供了有保证的log(n)时间成本答案 1 :(得分:4)
我认为你要问的更重要的问题是retainAll()函数的复杂性是什么。假设没有哈希或快速查找,我会假设时间复杂度为O(n ^ 2)。一个循环迭代列表,一个循环来比较每个项目。
答案 2 :(得分:1)
您使用的是错误的收藏品。
由于你使用普通ArrayList
这样做,复杂性不会很好,我不知道内部实现,但我猜它是二次的(因为它必须滚动两个列表),除非Java在进行交集之前,在内部将两个列表转换为集合。
您应该从Set
界面(here)开始,选择哪个系列更适合您的需求,我认为HashSet
(常数时间)或{{1} (对数但能够保持自然排序)将是最好的解决方案。
答案 3 :(得分:0)
简言之:
ArrayList.add()
为O(1)
。
ArrayList.retainAll(other)
为O(N1 * N2)
,其中N1
的大小为this
,N2
的大小为other
。 (实际成本取决于保留的元素与去除元素的比例。)
iter.hasNext()
迭代器, iter.next()
和O(1)
为ArrayList
。
这就像你期望的那样,基于对ArrayList作为Java数组的精神建模。