例如,如果数字是:
30, 12, 49, 6, 10, 50, 13
数组将是:
[10, 6, 30, 12, 49, 13, 50]
如你所见:
这些数字都是不同的和真实的。我需要最有效的算法。
答案 0 :(得分:15)
这可以在O(n)中完成:
当然,这假设所有元素都是不同的,否则有时会失败。
答案 1 :(得分:14)
假设数字都是不同的,最简单的方法可能是对数字进行排序,然后交错排序列表的前半部分和后半部分。这将保证您需要的高/低/高/低/高/低/ ....模式。
此算法为O(n log n)
,对于大多数用途而言应该足够有效,并且可以从标准库中的优化排序例程中受益。
如果数字不明显,则可能没有解决方案(例如,如果数字全部相等)
答案 2 :(得分:1)
有人将这个问题作为对this的骗局发布了,但是那里的解决方案比这里接受的解决方案更好,所以我想我会在这里发布。
基本上关键是每三个数字必须保持a < b > c
你看序列并将最大数字交换到中心。然后你递增2来得到a < b > c
之类的下一个序列并做同样的事情。
从技术上讲,解决方案仍然在O(n)中运行,就像接受的解决方案一样,但它是一个更好的O(n)并且它更简单,因为中位数算法的中位数很难实现。希望任何支持这个问题的人至少会看到这个解决方案,如果有人有兴趣,我可以发布代码。
答案 3 :(得分:0)
我不太了解复杂性,但这是我的想法。
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]