algorithm - 在序列中对重复进行分组的算法
问题描述
给定一个数字序列,例如:1, 2, 1, 2
.
是否有任何众所周知的算法来检测重复并将它们组合在一起以使生成的序列具有尽可能短的大小?
例如,对于前一个序列,结果将是(1, 2)x2
.
更多示例:
Input: 1, 1, 1, 2, 1, 1, 1, 2
Output: ((1)x3, 2)x2
Input: 1, 2, 1, 2, 1, 2
Output: (1, 2)x3
Input: 1, 1, 1, 2, 1, 2
Output: (1)x2, (1, 2)x2
编辑:
结果的长度(例如(1, 2)x2
)不包括有关分组和重复的任何附加信息(即忽略(),x
和之后的数字x
)。
例如,长度(1, 2)x2
实际上是 2。长度((1)x3, 2)x2
仍然是 2,因为我们只考虑属于原始序列的元素的数量(在本例中为 1 和 2)。
解决方案
您可以使用动态规划方法。n
让我们将输入序列定义为长度DP[i][j]
,并将子字符串压缩到的最小可能长度定义为以 index 开头并以 indexi
结尾j
。那么有两种情况:
始终如一地粘合:
DP[i][j] = min(DP[i][k] + DP[k + 1][j])
for allk
fromi
toj - 1
;重复:
DP[i][j] = min(DP[i][k])
对于所有这些k
将子字符串划分i..j
为相同的子字符串长度k - i + 1
。我认为最小值将是可能的最低值k
。
在这两个选项中,选择最小值。字符串本身也可以恢复(可以额外存储,也可以重新计算)。从 1 到DP[i][i] = 1
的所有初始数据。答案在(如果使用 1-index 数组)。i
n
DP[1][n]
推荐阅读
- android - 通过服务器传递 admob-click 以避免无效流量是否很好?
- sql - SQL 过滤来自连接的多个匹配项
- node.js - NodeJS:如何在不暴露证书内容的情况下安全地提供服务
- github - 没有标签的预提交挂钩?
- reactjs - 反应路由器
不能正常工作 - firebase - 如何在 Flutter 中滚动到底部工作表?
- git - 为不太懂技术的人编写 Git/GitHub 操作脚本
- python - Python - 应用程序和操作系统权限
- android - 如何禁用 dynatrace 以调试构建 android
- r - likert 包中的绘图问题 - 图像中的多余行