操纵 n 对算法的 O 有影响吗?
操作n
对算法的O有影响吗?
例如递归代码:
Public void Foo(int n)
{
n -= 1;
if(n <= 0) return;
n -= 1;
if(n <= 0) return;
Foo(n)
}
n
的重新分配是否会影响 O(N)
?对我来说听起来很直观...
通过删除常量,该算法是否具有 O(N)
?从技术上讲,由于它会将 n
减 2,因此不会产生与此相同的数学效果:
public void Foo(int n) // O(Log n)
{
if(n <= 0) return;
Console.WriteLine(n);
Foo(n / 2);
}
但是 n
减半不会导致 O(N )
,因为您只触及了 n
数量的一半?需要明确的是,我正在学习 O 表示法及其微妙之处。我一直在寻找类似于第一个例子的案例,但我很难找到这样一个具体的答案。
Does manipulating n
have any impact on the O of an algorithm?
recursive code for example:
Public void Foo(int n)
{
n -= 1;
if(n <= 0) return;
n -= 1;
if(n <= 0) return;
Foo(n)
}
Does the reassignment of n
impact O(N)
? Sounds intuitive to me...
Does this algorithm have O(N)
by dropping the constant? Technically, since it's decrementing n
by 2, it would not have the same mathematical effect as this:
public void Foo(int n) // O(Log n)
{
if(n <= 0) return;
Console.WriteLine(n);
Foo(n / 2);
}
But wouldn't the halving of n
contribute to O(N)
, since you are only touching half of the amount of n
? To be clear, I am learning O Notation and it's subtleties. I have been looking for cases such that are like the first example, but I am having a hard time finding such a specific answer.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当谈论 O 表示法时,n 本身的重新分配并不是真正重要的。作为一个例子,考虑一个简单的 for 循环:
在这个算法中,我们做了 n 次某事。这相当于以下算法
并且相当于您提出的第一个递归函数。因此,真正重要的是与输入大小(即 n 的原始值)相比,完成了多少计算。
因此,所有这三种算法都是 O(n) 算法,因为这三种算法每次都会将“输入大小”减少 1。即使他们将其增加 2,它仍然是一个 O(n) 算法,因为使用 O 表示法时常数并不重要。因此下面的算法也是一个 O(n) 算法。
或者
但是,正如您在评论中所写,您提出的第二个递归函数是 O(log n) 算法(即使它没有基本情况并且技术上会运行直到堆栈溢出)。直观上,当每次将输入大小减半时,这恰好对应于原始输入数以二为底的对数取对数。考虑以下情况:
n = 32。算法每次减半:32 -> 16-> 8-> 4-> 2-> 1.
我们总共进行了 5 次计算。相当于 log2(32) = 5。
回顾一下,重要的是原始输入大小以及与此输入大小相比完成了多少计算。无论什么常数可能影响计算,都无关紧要。
如果我误解了您的问题,或者您有后续问题,请随时评论此答案。
The reassignment of n itself is not really what matters when talking about O notation. As an example consider a simple for-loop:
In this algorithm, we do something n times. This would be equivalent to the following algorithm
And is equivalent to the first recursive function you presented. So what really matters is how many computations is done compared to the input size, which is the original value of n.
For this reason, all these three algorithms would be O(n) algorithms, since all three of them decreases the 'input size' by one each time. Even if they had increased it by 2, it would still be a O(n) algorithm, since constants doesn't matter when using O notation. Thus the following algorithm is also a O(n) algorithm.
or
However, the second recursive function you presented is a O(log n) algorithm (even though it does not have a base case and would techniqually run till the stack overflows), as you've written in the comments. Intuitively, what happens i that when halving the input size every time, this exactly corresponds to taking the logarithm in base two of the original input number. Consider the following:
n = 32. The algorithm halves every time: 32 -> 16 -> 8 -> 4 -> 2 -> 1.
In total, we did 5 computations. Equivalently log2(32) = 5.
So to recap, what matters is the original input size and how many computations is done compared to this input size. Whatever constant may affect the computations does not matter.
If I misunderstood your question, or you have follow up questions, feel free to comment this answer.