这个问题可以重新表述为:
将字符串 S 转换成仅包含 'a' 的字符串最少需要多少步操作?
定义:
在字符串中,连续的子序列被视为相同字符的序列。最小的连续子序列自然是单个字符。如果你将小的子序列规范化,你会得到更大的子序列,最终会达到一个子序列——整个字符串。
规范化目标:
只能将字符向上或向下移动,所以一个字符本身就是一系列向上和向下移动的步骤。表示一个字符的最坏情况是字母表中间的字母,至少需要 len(alphabet) / 2
步才能描述完毕。在字母表 {a..z}
中,最坏的情况是 'm'
和 'n'
。
由于我们希望最小化移动步骤,因此我们需要将字母 C <= m
向下移动,将那些 C >= n
的字母向上移动。因此,为了最小化规范化过程,我们必须找到需要相同规范化步骤的最大子序列。例如,如果我们有一个目标 zzzzbzzzz
,我们知道最小化的方向是 UUUUDUUUU
——U 表示向上,D 表示向下。
规范化操作:
对于每个移动步骤,计数器都会递增,从而得到将字符串转换所需的最少步骤数。考虑上述例子,我们可以采取以下步骤:
# = 0 | zzzzbzzzz | UUUUDUUUU (choose the smallest subsequence to normalize)
# = 1 | zzzzazzzz | UUUUDUUUU (since 'a' is the base character, we choose
the move that increases the largest subsequence;
if 'a' was the first or last character,
moving it would simply be overhead)
# = 2 | zzzzzzzzz | UUUUUUUUU (choose the subsequence to normalize)
# = 3 | aaaaaaaaa | _________ (choose the subsequence to normalize)
另一个例子,目标字符串为
abcxyz
:
# = 0 | abcxyz | _DDUUU (choose the smallest subsequence to normalize)
# = 1 | aabxyz | __DUUU (choose the smallest subsequence to normalize)
# = 2 | aaaxyz | ___UUU (choose the smallest subsequence to normalize)
# = 3 | aaayza | ___UU_ (choose the smallest subsequence to normalize)
# = 4 | aaazaa | ___U__ (choose the smallest subsequence to normalize)
# = 5 | aaaaaa | ______ (choose the smallest subsequence to normalize)
编辑:
正如@user1884905所指出的那样,这个解决方案,就其提出的方式而言,并不是最优解。对于目标字符串mn
,该算法并不能得到最优解:
# = 0 | mn | DU (choose the smallest subsequence to normalize)
# = 1 | ln | DU (choose the smallest subsequence to normalize)
# = 2 | kn | DU (choose the smallest subsequence to normalize)
...
# = 12 | an | _U (choose the smallest subsequence to normalize)
# = 13 | ao | _U (choose the smallest subsequence to normalize)
# = 14 | ap | _U (choose the smallest subsequence to normalize)
...
# = 24 | aa | __ (choose the smallest subsequence to normalize)
这不是最优的,因为接下来的步骤需要更少的移动:
#0 #1 #2 ... #12
mn -> mm -> ll -> ... -> aa
也许贪心算法的最优子结构在于减少字符串中字符之间的全局距离,而不是专注于这些字符与基本情况(
'a'
)之间的差异。
zzzzbzzzz
需要三步才能到达?不能用aaaaaaaaa => zzzzzzzzz => zzzzbzzzz
(2 步)的方法吗? - John Dvorakz
首先回到a
。 - jxh