我在接受采访时被问到以下问题,我仍然在想一种有效的方法。
你有一个数组,其数字代表桶中液体的百分比。你还有一个带有方法的API:combine(int x,int y)
,它在数组中占两个输入百分比,并将液体从一个桶组合到另一个桶中。通过使用此信息,您必须找到100%液体可能存在的最大桶数。
示例1。数组:10,15,20,35,55,65
Ans :每桶数量为2。
自combine(65,35)
---一个100%桶,
combine(55,20)
- 75%桶,下一个combine(75,15)
- 90%下一个combine(90,10)
- 100% - 1桶
总共2桶
示例2:99,99,99
答案:自combine(99,99)
以来,每桶数量为1 - 你得到一个100%的桶,其余的液体被浪费了,你不能合并任何其他桶与第三个99%的桶,使其成为100
注意:一旦您将液体从一个桶倒入另一个桶中,您就无法再次使用它
例如:combine(55,15)
- 70%桶。您可以使用70%的桶,但不能使用55%和15%的桶。
答案 0 :(得分:2)
您可能确实会查看bin打包问题的算法。 This student paper表示其中四个。具有最佳近似值的是降低First Fit算法。
归结为快速排序(就地,平均O(nlogn)时间复杂度和最坏情况下的O(n2)),然后是First Fit。
First Fit下来按顺序扫描垃圾箱,并将新物品放在第一个容器中,该容器足够容纳它。如果没有当前对象适合的bin,则启动一个新bin。
对于O(nlogn)复杂度的FF,使用Max Winner Tree数据结构。它有n个外部节点(播放器)和n-1个内部节点(每个匹配的赢家), 获胜者是具有最大价值的玩家。
答案 1 :(得分:1)
假设给定数组中的所有百分比都小于100(在任何情况下,如果元素大于或等于100,我们可以立即计算并删除它们),每个100%的桶不能从少于两个数组创建元素和100%桶的数量不能超过数组之和除以100.因此,检查的可能性受以下因素约束:
maxNumBarrels array = min (div (sum array) 100) (div (length array) 2)
以下Haskell代码提供了函数divide
,它将数组划分为n个分区的所有变体而不重复(即,忽略分区中的分区顺序和元素顺序)。函数maxBarrels
向后搜索,首先将数组划分为maxNumBarrels分区(搜索结果为maxNumBarrels元素的总和> = 100),然后逐渐减少分区数,直到找到答案或为null set返回。
import Data.Map (adjust, fromList, toList)
divide xs n = divide' xs (zip [0..] (replicate n [])) where
divide' [] result = [result]
divide' (x:xs) result = do
index <- indexes
divide' xs (toList $ adjust (x :) index (fromList result)) where
populated = map fst . filter (not . null . snd) $ result
indexes = populated ++ if any (null . snd) result
then [length populated]
else []
maxBarrels xs = allDivided maxNumBarrels where
maxNumBarrels = min (div (sum xs) 100) (div (length xs) 2)
allDivided count | count == 0 = []
| not (null divided) = divided
| otherwise = allDivided (count - 1)
where divided = filter ((==count) . length)
. map (filter ((>=100) . sum))
. map (map snd)
. divide xs $ count
输出:
*Main> maxBarrels [10,15,20,35,55,65]
[[[55,20,15,10],[65,35]],[[55,35,10],[65,20,15]]]
*Main> maxBarrels [99,99,99]
[[[99,99,99]]]
*Main> maxBarrels [99,99,99,10,15,25,35,55,65]
[[[15,10,99],[25,99],[35,99],[65,55]] ...(the first of 144 immediate results)...