我正在准备我的考试并且在运行时分析方面遇到一些麻烦。我有两种方法,我对运行时分析感到困惑:
public boolean findDuplicates(String [] arr) {
Hashtable<String,String> h = new Hashtable<String,String>();
for (int i = 0; i < arr.length; i++) {
if (h.get(arr[i]) == null)
h.put(arr[i], arr[i]);
else
return true;
}
return false;
}
假设散列函数只对任何键使用O(1),运行时间是否只是O(n),因为在最坏的情况下,运行整个数组?如果每个哈希函数需要持续的时间来评估,我是否会沿着正确的方向思考这个问题?
我遇到的另一个问题似乎要复杂得多,我不确切知道如何处理这个问题。假设这些是arrarlists。
public boolean makeTranslation(List<Integer> lst1, List<Integer> lst2) {
//both lst1 and lst2 are same size and size is positive
int shift = lst1.get(0) - lst2.get(0);
for (int i = 1; i < lst1.size(); i++)
if ( (lst1.get(i) - lst2.get(i)) != shift)
return false;
return true;
}
在这种情况下,get操作应该是常量,因为我们只是检索特定的索引值。但是在for循环中,我们都将它与shift进行比较,并且迭代所有元素。这究竟会如何转化为运行时间?
非常感谢一个有用的解释,因为我最难理解运行时分析而不是本课程中的任何内容,而我的决赛将在下周进行。
答案 0 :(得分:1)
简短回答:两种方法都具有O(n)
的时间复杂度。
对于哈希,显然get
和put
操作都需要一段时间。
对于列表,如果使用ArrayList
实现(很可能),get
方法也需要恒定时间。这是因为Java中的ArrayList
是由数组支持的List
。
标准Java库中的ArrayList.get(index)
代码:
public E get(int index) {
RangeCheck(index);
return (E) elementData[index];
}
RangeCheck
可能进行了两次比较,即恒定时间。从array
返回值显然是恒定的时间。因此,get
的{{1}}方法需要不变的时间。
至于你在OP中提到的具体问题:
但是在for循环中,我们都将它与shift相比较 迭代所有元素。这究竟是如何转化为运行 时间?
ArrayList
需要一段时间。 lst1.get(i)
需要一段时间。因此,lst2.get(i)
需要恒定的时间。同样适用于lst1.get(i) - lst2.get(i)
。这个想法是恒定数量的恒定时间操作的总和仍然是恒定的时间。由于循环迭代最多(lst1.get(i) - lst2.get(i)) != shift
次,因此总时间为n
,即O(n),其中C是常数。
而且......在最后一次之前对the big O notation进行简要回顾是绝对不会伤害的。)
答案 1 :(得分:0)
Big-O表示法不是很准确,因为您省略了常数因子和低阶项。因此,即使你有2次常数运算n次,它仍然是O(n)。实际上,它将是(1 + 1)n = 2n,但在ordo-notation中我们将它向下舍入(即使它是10000n)。因此,对于这两种情况,运行时间将为O(n)。
实际上,我建议在最坏的情况下输入每个循环和每个操作的成本。从最里面的嵌套级别开始并向外相乘(只有每个级别的最高成本)。
例如:
for (int i = 0; i<n; i++) { //n times
//log n operation
for (int i = 0; i<n; i++) { //n times
//constant operation
}
}
这里,我们有n *(log(n)+ n * 1)= O(n * n)为n> log(n)
答案 2 :(得分:0)
通常,O()表示算法的复杂性,通常是操作的数量,假设每个操作的成本是恒定的。例如 O(1000n) < / strong>类似于编写 O(n) ,因为每个操作都花费 1000 ,并且有 n 操作。
因此假设 获取 且 put 对于每个值都是常量(取决于库实现),时间两者都是 O(n) 。 有关更多信息,请参阅 http://en.wikipedia.org/wiki/Big_O_notation
答案 3 :(得分:0)
值得回应,但这两项操作都是 O(n)(对于#2,这是最糟糕的情况)。需要注意的关键是每次迭代完成的关键操作数量。
对于您的第一个片段,Hashtable
有点像红色鲱鱼,因为访问时间不会是循环中最大的操作。情况也是如此,因为Hashtable
只是new
'd,您总是将 n 元素插入其中。
对于你的第二个片段,你有机会提前结束。如果下一个元素的差异不是shift
,那么您在那里返回false
然后,这只是一个操作。在最糟糕的情况下,您将浏览所有 n 并返回。