例如,如果数字是:
30, 12, 49, 6, 10, 50, 13
数组将会是:
[10, 6, 30, 12, 49, 13, 50]
正如您所看到的:
- 6比10和30都小,
- 49比12和13大等等。
这些数字都是不同且真实的。我需要最有效率的算法。
这可以在O(n)时间内完成:
当然,这假设所有元素都是不同的,否则有时会失败。
O(n)
中找到中位数元素,并将数组分成小和大,然后交错排列,O(n)
。是的,对于实际目的而言,快速的O(n log(n))
可能比慢的O(n)
更好。 - A. Webba < b > c
,您查看序列并将最大的数字交换到中心。然后,您增加2以进入下一个序列,例如a < b > c
,并执行相同的操作。For even length lists:
(For our odd length example,
put 30 aside to make the list even)
1. Split the list into chunks of 2 => [[12,49],[6,10],[50,13]]
2. Sort each chunk => [[12,49],[6,10],[13,50]]
3. Reverse-sort the chunks by
comparing the last element of
one to the first element of
the second => [[12,49],[13,50],[6,10]]
For odd length lists:
4. Place the removed first element in
the first appropriate position => [30,12,49,13,50,6,10]
Haskell 代码:
import Data.List (sortBy)
import Data.List.Split (chunksOf)
rearrange :: [Int] -> [Int]
rearrange xs
| even (length xs) = rearrangeEven xs
| null (drop 1 xs) = xs
| otherwise = place (head xs) (rearrangeEven (tail xs))
where place x (y1:y2:ys)
| (x < y1 && y1 > y2) || (x > y1 && y1 < y2) = (x:y1:y2:ys)
| otherwise = place' x (y1:y2:ys)
place' x (y1:y2:ys)
| (x < y1 && x < y2) || (x > y1 && x > y2) = (y1:x:y2:ys)
| otherwise = y1 : (place' x (y2:ys))
rearrangeEven = concat
. sortBy (\a b -> compare (head b) (last a))
. map sort
. chunksOf 2
输出:
*Main> rearrange [30,12,49,6,10,50,13]
[30,12,49,13,50,6,10]
*Main> rearrange [1,2,3,4]
[3,4,1,2]
[3,4,0,1,2]
,它返回[1,0,2,4,3]
,这是无效的,因为2
大于0
但小于4
。在这种情况下,有效的解决方案可能是[0,4,1,3,2]
。使用我编写的QuickCheck测试工具包找到。 - hammarprop_correct (Distinct xs) = odd (length xs) || valid (rearrange xs)
然后我得到了这个结果:+++ OK, passed 100 tests.
- גלעד ברקן
O(n!)
的复杂度... - Lukas Eder