algorithm - 解决单元求和难题的最有效算法是什么?
问题描述
单元格和拼图定义如下:
给定两组非负整数X = { x 1 , x 2 ,..., x m } 和Y = { y 1 , y 2 ,..., y n },填充m网格中的每个单元格具有单个非负整数的行和n列,使得x i是每个i ≤ m的第i行中的单元格的总和,并且使得y j是每个j的第j列中的单元格的总和≤ n。
例如,如果X = {7, 13} 和Y = {8, 9, 3},那么您的目标是替换以下网格中的问号:
? + ? + ? = 7
+ + +
? + ? + ? = 13
= = =
8 9 3
一个有效的解决方案是:
3 + 1 + 3 = 7
+ + +
5 + 8 + 0 = 13
= = =
8 9 3
对于任意大的m和n,你如何解决这个难题?此外,对于您选择的方法,您是否知道时间复杂度,您能否判断它是否是最有效的算法?
解决方案
这是一个线性时间算法 (O(m + n) 假设我们可以输出一个稀疏矩阵,这是渐近最优的,因为我们必须读取整个输入;否则 O(mn),这是最优的,因为我们必须写入整个输入输出)。
用第一行总和和第一列总和的最小值填写左上角问号。如果第一行总和等于最小值,则在该行的其余部分输入零。如果第一列总和等于最小值,则在该列的其余部分输入零。如果它们仍然存在并递归,则通过从第一行/列中减去新值来提取子问题。
在你的例子中:
? + ? + ? = 7
+ + +
? + ? + ? = 13
= = =
8 9 3
7 和 8 的最小值是 7。
7 + 0 + 0 = 7
+ + +
? + ? + ? = 13
= = =
8 9 3
提取子问题。
? + ? + ? = 13
= = =
1 9 3
13 和 1 的最小值为 1。
1 + ? + ? = 13
= = =
1 9 3
提取子问题。
? + ? = 12
= =
9 3
继续前进,直到我们得到最终解决方案。
7 + 0 + 0 = 7
+ + +
1 + 9 + 3 = 13
= = =
8 9 3
推荐阅读
- javascript - 创建一个可访问的列表,其中每个 li 元素都有一些复杂的内容
- python - 从列表创建数据框
- selenium - I heard from an acquaintance that it is possible to programmatically cut Google's reCapcha so that it doesn't show image verification, is this true?
- django - 如何为 Django App 授权令牌流程创建流程
- swift - Swift:如何将另一个框架包含到您的框架中
- reactjs - TypeError:validateOptions 不是函数
- yaml - 将来自多个 SNS 主题的消息发送到单个 Amazon SQS
- stata - 当我在双向分散的 ylabel() 选项中包含破折号时出错
- javascript - 如何在 PHP 中的 MVC 上使用 AJAX
- angularjs - 谷歌云角度托管站点显示指定的密钥不存在