这是来自https://www.dailycodingproblem.com/的问题:
给出一个字符串,找到可以通过插入 单词中尽可能少的字符数。如果有 超过一个可以形成的最小长度的回文 在字典上最早的(按字母顺序排列的第一个)。
例如,给定字符串“ race”,您应该返回“ ecarace”, 因为我们可以在其中添加三个字母(这是 做回文)。还有其他七种回文 从“种族”中添加三个字母,但“ ecarace”排在第一位 按字母顺序。
作为另一个示例,给定字符串“ google”,您应该返回 “ elgoogle”。
它类似于this SO问题或this GeeksforGeeks帖子。相似,但不相同;他们都没有提供任何有关复发的解释,就好像他们是凭空抽出了溶液,而且他们也没有重建溶液,更不用说按字典顺序最早的溶液了。
经过一番思考,我的理解如下:
对于任何字符串
s[i..j]
,请注意,如果s[i] == s[j]
,则 使其回文所需的插入次数与 使s[i+1..j-1]
回文所需的插入次数。但是,如果
s[i] != s[j]
可以将s[i..j-1]
转换为 回文,然后在开头插入s[j]
,或进行转换s[i+1..j]
返回回文,并在末尾插入s[i]
。既然我们是 在寻找最少插入次数的情况下,我们将选择 至少两个选项。插入次数多于 所选子问题所需的插入次数(对于 在开头或结尾添加一个字符。
我如何重建词典上最早的解决方案?
答案 0 :(得分:2)
首先,让我们回答“如何重建解决方案”,然后集中精力订购。假设您将插入次数存储在2D矩阵insertions[start][stop]
中,则只需回溯您的步骤,即可“收集”插入的字符。我们需要一个新的数组来存储输出字符串,其长度等于我们的起始字符串加上最少的插入次数。我们还将存储两个索引,指向从正面到阵列的下一个可用点。
首先比较当前子字符串的第一个和最后一个字母,如果相等,则将输出字符串都分配给这两个字符串,分别位于前面和后面的下一个可用位置。例如,如果我们有FYRF
作为当前子字符串,我们将分配输出字符串F..F
,其中.
是不确定的字符。然后我们的子字符串变为s[i+1..j-1]
或YR
。
如果两个字符不匹配,我们将比较insertions[i+1][j]
和insertions[i][j-1]
中的记录,看哪个更小(至少其中一个比{{1 }})。如果它们相等,则选择一个(我们将在稍后返回)。在输出字符串中分配与我们复制/插入的子字符串的字母相对应的字符,在输出字符串的下一个可用的前后索引处。也就是说,在insertions[i][j]
的情况下,如果我们决定为JLL
添加一个J
,我们将使用子字符串JLLJ
,因此我们将存储{{1 }}和s[i+1..j]
放在输出字符串J
中。如果我们的输出字符串已经包含J
,那么我们将存储J..J
。我们重复整个过程,直到分配了所有字符。
现在,按照字典顺序进行排序。对于上一段中AR....RA
和ARJ..JRA
相等的情况,我们不应该随机选择其中之一。相反,我们应该按字典顺序比较insertions[i+1][j]
和insertions[i][j-1]
,如果s[i]
首先出现,则将s[i+1]
插入输出字符串/继续进行s[i]
。否则,请使用s[i]
/ insertions[i+1][j]
。这将为我们提供所有可用选项中按词典顺序排列的最快字符串。
答案 1 :(得分:1)
这里的OP:@ dillon-davis的答案是正确的(被否决),尽管那时我自己已经知道了。我已经在问题中提供了基本算法的说明,@ dillon-davis提供了重构的说明,为完整起见,这是Scala中的工作代码。
list1=['student1',10,20,40,'student2',20,20,40,'student3',20,30,40,'student4',20,10,30]
list2=[]
for i in range(0, len(list1), 4):
list2.append(list1[i])
sum = list1[i+1]+list1[i+2]+list1[i+3]
list2.append(sum)
print(list2)