Điều tốt nhất tôi có thể đưa ra là tạo ra một ma trận tổng của mỗi cặp, sau đó hợp nhất các hàng với nhau, sắp xếp hợp nhất a-la. Tôi cảm thấy như tôi đang thiếu một số hiểu biết đơn giản mà sẽ tiết lộ một giải pháp hiệu quả hơn nhiều.
thuật toán của tôi, trong Haskell:
matrixOfSums list = [[a+b | b <- list, b >= a] | a <- list]
sortedSums = foldl merge [] matrixOfSums
--A normal merge, save that we remove duplicates
merge xs [] = xs
merge [] ys = ys
merge (x:xs) (y:ys) = case compare x y of
LT -> x:(merge xs (y:ys))
EQ -> x:(merge xs (dropWhile (==x) ys))
GT -> y:(merge (x:xs) ys)
Tôi tìm thấy một sự cải thiện đáng kể, một trong đó là dễ dàng cho lười biếng mã hóa dựa trên luồng. Thay vì hợp nhất các cột một cách khôn ngoan, hãy hợp nhất tất cả các cột cùng một lúc. Lợi thế là bạn bắt đầu nhận được các yếu tố của danh sách ngay lập tức.
-- wide-merge does a standard merge (ala merge-sort) across an arbitrary number of lists
-- wideNubMerge does this while eliminating duplicates
wideNubMerge :: Ord a => [[a]] -> [a]
wideNubMerge ls = wideNubMerge1 $ filter (/= []) ls
wideNubMerge1 [] = []
wideNubMerge1 ls = mini:(wideNubMerge rest)
where mini = minimum $ map head ls
rest = map (dropWhile (== mini)) ls
betterSortedSums = wideNubMerge matrixOfSums
Tuy nhiên, nếu bạn biết bạn đang đi để sử dụng tất cả các khoản tiền, và không có lợi thế để nhận được một số trong số họ trước đó, đi với 'foldl merge []
', vì nó nhanh hơn.
Nguồn
2008-08-03 21:36:25
Tôi nghĩ rằng đây là O (n^3) vì có 'góc trên cùng bên trái' tiềm năng ở mỗi giai đoạn. –
Bạn có thể thực hiện thuật toán này trong thời gian O (n^2 log n) bằng cách lưu trữ mục nhập chưa được đầu tiên đầu tiên trong mỗi hàng trong hàng đợi ưu tiên, nhưng gần như không có gì tốt hơn là tạo tất cả các khoản tiền và sắp xếp. –
Nếu bạn có hai danh sách thay vì một, chiều dài m và n với m
dfeuer