假设笛卡尔坐标中有一组点,并且想要找到四个极值点,例如x-min,y-min,x-max和y-max。
如果使用x和y坐标分别对点进行排序,则需要O(n log n)* 2.
要找到没有排序的四个极值点,它将需要O(n)* 4.(它必须比较从开始到结束的点)
一旦我们对点进行排序,找到接下来的四个极值点可以采取O(1),不是吗?
但是如果没有排序,它将再次需要O(n)* 4。还是O(n-4)* 4?下次O(n-8)* 4,O(n-12)* 4等等。
因此,如果我们想要递归地找到四个极值点,直到没有找到的点。排序需要O(n log n),但没有排序需要多长时间?是O(n)?
在这种情况下,通过排序递归查找四个极值点会更好吗?
答案 0 :(得分:0)
一旦我们对点进行排序,找到接下来的四个极值点可以采取O(1),不是吗?
是
但是如果没有排序,它将再次需要O(n)* 4。还是O(n-4)* 4?下次O(n-8)* 4,O(n-12)* 4等等。
是
因此,如果我们想要递归地找到四个极值点,直到没有找到的点。排序需要O(n log n),但没有排序需要多长时间?是O(n)吗?
通过“递归”,你可能意味着“迭代地”。但是否则,如果没有排序,则需要O(n ^ 2)。不要忘记你需要找到 n 连续的极值,这会使这种方法的复杂性乘以n。
在这种情况下,通过排序递归查找四个极值点会更好吗?
确实如此,因为复杂性较低。
答案 1 :(得分:0)
常数因素在Big O复杂符号中并不重要。 O(100000n)
与O(n +/- 100000)
相同,与O(n)
相同。
递归查找极值点直到找不到要点将花费O(n^2)
时间,因为对于i
(基于1)极值点,您必须执行{{ 1}}比较,即第一个n - i + 1
比较,第二个n
等等,总共进行n - 1
比较,与n(n + 1)/2
相同O(n^2)
是更重要的因素。
另一方面,对点进行排序将花费n^2
时间(假设快速排序或合并排序)。按顺序查找O(n log n)
极值点会带你n
(必须迭代排序的数组一次)如果你必须使用不同的表示法。在任何一种情况下,时间复杂度将保持O(n)
,因为它是更重要的因素。
所以是的,排序是更有效的方法。
答案 2 :(得分:0)
对于给定的轴,您应该能够在一次迭代中找到最大值和最小值(o(n))。
.locals init (
[0] float64 V_0
)
IL_0001: ldc.r8 182273
IL_000a: call float64 [mscorlib]System.Math::Sin(float64)
IL_000f: ldc.r8 0.888
IL_0018: add
IL_0019: stloc.0 // save to local
IL_001a: br.s IL_001c // basically nop
IL_001c: ldloc.0 // V_0 // pop from local to stack
IL_001d: ret // return
那样就是o(n)* 2。所以,你可以使用它而不是排序,但这只是你必须做一次。
如果您需要为所有点执行此操作,则可以进行排序。
答案 3 :(得分:0)
排序减少到你的问题:给定一组实数,[x1,...,xn],构造2d点(x1,x1),(x2,x2),...,(xn, XN)。一旦你迭代地找到了所有极值点,直到没有剩下的点,你就可以轻松地重建x1,...,xn的排序版本。这意味着没有解决问题的算法比排序更快。
由于您也可以通过排序解决问题,因此您已经证明排序的复杂性是您问题的上限和下限。