सबसे अच्छा मैं साथ आ सकता हूं कि प्रत्येक जोड़ी की रकम का मैट्रिक्स तैयार किया जाए, और फिर पंक्तियों को एक साथ लाएं, एक ला मर्ज सॉर्ट करें। मुझे लगता है कि मुझे कुछ सरल अंतर्दृष्टि याद आ रही है जो एक अधिक कुशल समाधान प्रकट करेगी।
मेरे एल्गोरिथ्म, हास्केल में:
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)
मैं एक छोटी सी सुधार, एक है कि आलसी धारा आधारित कोडिंग के लिए और अधिक उत्तरदायी है पाया। कॉलम जोड़ी के अनुसार विलय करने के बजाय, उन सभी को एक साथ मिलाएं। लाभ यह है कि आप तुरंत सूची के तत्व प्राप्त करना शुरू करते हैं।
-- 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
हालांकि, अगर आप जानते हैं कि आप रकम का उपयोग करने जा रहे हैं, और उनमें से पहले कुछ हो रही करने के लिए कोई लाभ है, 'foldl merge []
' के साथ जाने के रूप में यह सबसे तेज़ है।
स्रोत
2008-08-03 21:36:25
मुझे लगता है कि यह ओ (एन^3) है क्योंकि प्रत्येक चरण में एन संभावित 'टॉप बाएं कोनों' हैं। –
आप प्राथमिकता कतार में प्रत्येक पंक्ति में पहली अनपढ़ प्रविष्टि को संग्रहीत करके ओ (एन^2 लॉग एन) समय में इस एल्गोरिदम को कार्यान्वित कर सकते हैं, लेकिन असम्बद्ध रूप से यह सभी रकम और सॉर्टिंग उत्पन्न करने से बेहतर नहीं है। –
यदि आपके पास एक के बजाय दो सूचियां हैं, लंबाई एम और एन के साथ एम
dfeuer