https://leetcode.com/problems/minimum-number-of-moves-to-make-palindrome/
贪心,比较难想到
个人解答
class Solution:def minMovesToMakePalindrome(self, s: str) -> int:s = list(s)res = 0while s:i = s.index(s[-1])if i == len(s) - 1:res += len(s) // 2del s[-1]else:res += idel s[i]del s[-1]return res
题目分析
就贪心就好,哎,想的太多了,没做出来。
看解答,其实就是对于每一个端点的值,找出另一端最靠近那端的index。
为什么这么可以呢?需要验证两个部分:
- 最短的更改,最终的端点一定是两端的其中一个
- 最短的更改,两遍选任意一个端点都可以
第一点,以a ... b为例,如果a/ b作为端点,则匹配之后,可以剔除掉,不影响之后的交换。如果a/b匹配到中间,那么在之后的交换过程中,会经过匹配好的a/b,会多出两个swap。
最优情况下,不把a/b作为端点的swap数量和作为端点的swap数量相同,比如:acbacb
第二点,考虑一个通用的例子:a ... b ... a ... b,第二个a是最右边的a,第一个b是最左边的b。那么想要匹配两者,必然会经历ab ... ba这个过程:ab ... a ... b-> ba ... a ... b -> ba ... ab<- **ab ... ba**a ... b ... ab-> a ... b ... ba -> ab ... ba<- **ab ... ba**
两者最后都需要同样的步数,因此选择哪个无所谓。
所以简单贪心就好了。
另外针对不能匹配的点,说明是最中心的,需要移动到中心。
