如果hasTwoTrueValues
数组中至少有两个值为true
,则方法boolean
会返回true
。为所提出的所有三种实现提供Big-O运行时间。
// 版本1
public boolean hasTwoTrueValues(boolean[] arr) {
int count = 0;
for(int i = 0; i < arr.length; i++)
if(arr[i])
count++;
return count >= 2;
}
// 版本2
public boolean hasTwoTrueValues(boolean[] arr) {
for(int i = 0; i < arr.length; i++)
for(int j = i + 1; j < arr.length; j++ )
if(arr[i] && arr[j])
return true;
}
// 版本3
public boolean hasTwoTrueValues(boolean[] arr) {
for(int i = 0; i < arr.length; i++)
if(arr[i])
for(int j = i + 1; j < arr.length; j++)
if(arr[j])
return true;
return false;
}
这些是我的答案:
O(n)
O(n^2)
O(n^2)
我对这个Big-O符号真的很陌生,所以如果我的答案是正确/不正确,我需要指导。如果我错了,你能解释一下并帮助我学习吗?
答案 0 :(得分:4)
版本1非常简单并且是线性的,因此其运行时间平均为O(n)。
版本2更有趣。它以n(n-1)平均运行,即O(n 2 )。在这个循环中有一个早期return
,所以它肯定可能早在前两个元素中断。
版本3比较棘手。你必须小心这一点。仅当arr[i]
为true
时,第二个循环才会运行。必须将它的运行时放入不同的类别中。
可以肯定地说,版本3的平均和最差运行时将是O(n 2 )。最好的是O(n),这绝对是可能的。
答案 1 :(得分:0)
简而言之,最坏情况运行时间是:
版本1:O(n)
版本2:O(n^2)
版本3:O(n)
<小时/> 更详细的分析......
对于此算法,您必须考虑最佳情况,最差情况和平均情况运行时才能进行有意义的比较。
对于他们每个人,以下应该举例说明:
bestCase = [ true, true, ...] // the first two are true
worstCase = [ false, false, ..., false] // all are false
averageCase = [ true, ..., true, ..., false // second true value is found about half-way
对于所有算法,最佳情况下的运行时间为O(2)
,意味着恒定时间。
在最坏的情况下,您的第一个算法是O(n)
,这意味着线性运行时。
但是,在最坏的情况下,您的第二个算法将非常具体地退化,因为在每个步骤中您只需要检查一个元素。您最终会得到总和n + (n-1) + (n-2) + ...
,它将评估为n(n-1)/2
,正如您所说,它位于O(n^2)
,并且以二次方式增长。
在所有都是假的“最坏情况”中(我们将会看到,实际上这不是版本3 的最坏情况),您的第三个算法实际上是在线性时间内运行的,因为if
语句阻止第二个循环运行。
事实证明,版本3 永远不会以二次方式运行:它在平均和最差情况下都是线性的,因为它会线性扫描第一个{ {1}},然后在找到之后线性地扫描其余的true
,尽管它甚至不起作用!
因为在内部for循环中有两个返回值,一旦遇到第一个true
值,如果下一个直接邻居是true
,它将返回true
。但是,如果下一个直接邻居是true
,它会立即返回false
并且不会检查任何其他值。这意味着输入:
false
只要看到第二个错误值, 版本3 就会返回false。 (从技术上讲,我假设您希望在for循环中执行此[ true, false, true ]
,在这种情况下,您还需要添加return false
,同样需要添加第一个版本。虽然并非总是必要,但它有助于澄清究竟发生了什么,特别是因为这与你当前的缩进不匹配。当缺席时,只有紧随其后的语句包含在循环/ if body中。)我怀疑,即使实现正确,* 版本3 仍将在输入上具有线性的更糟糕的运行时间:
{ }
第一个true将导致它在内循环中扫描[true, false, false, ..., false]
次,但是外循环将继续运行到n而不再运行内循环,总共给出2n-1个操作,当然在n
。
如果你的O(n)
是正确的并且只是你的缩进是错误的,那么这些分析可能需要稍微修改一下,但这是你需要应用于大O问题的思维方式(一般的渐近分析。)