我正在解决LeetCode问题2193. Minimum Number of Moves to Make Palindrome:
您将看到一个仅由小写英文字母组成的字符串
s
.在One move中,您可以 Select
s
中的任意两个adjacent字符并交换它们.返回the 101 needed to make
s
a palindrome.请注意,将生成输入,以便始终可以将
s
转换为回文.
我用这个打字代码解决了这个问题:
function minMovesToMakePalindrome(s: string) {
if (s.length <= 1) return 0;
if (s[0] === s[s.length - 1]) return minMovesToMakePalindrome(s.slice(1, s.length - 1))
let leftSwapsCost = s.length;
let rightSwapsCost = s.length;
for (let i = 0; i < s.length; i++) {
if (s[i] === s[0]) {
// we should swap with the last element
rightSwapsCost = Math.min(rightSwapsCost, s.length - 1 - i)
} else if (s[i] === s[s.length - 1]) {
// we should swap with the first element
leftSwapsCost = Math.min(leftSwapsCost, i)
}
}
if (leftSwapsCost <= rightSwapsCost) {
const newString = [s[leftSwapsCost], ...s.slice(1, leftSwapsCost), s[0], ...s.slice(leftSwapsCost + 1)].join('');
console.log('left: ' + newString + ' cost: ' + leftSwapsCost)
return leftSwapsCost + minMovesToMakePalindrome(newString.slice(1, s.length - 1))
} else {
const newString = [...s.slice(0, s.length - 1 - rightSwapsCost), s[s.length - 1], ...s.slice(s.length - rightSwapsCost, s.length - 1), s[s.length - 1 - rightSwapsCost]].join('');
console.log('right: ' + newString + ' cost: ' + rightSwapsCost)
return rightSwapsCost + minMovesToMakePalindrome(newString.slice(1, s.length - 1))
}
};
基本上,我是在遍历字符数组(字符串),查找与第一个项目相等的项目的索引,然后计算将每个项目与最后一个项目进行交换并将其最小值存储在rightSwapsCost
中的成本.
对于与最后一个项目相等的项目也是一样的:我计算将它们与第一个项目交换的最小成本,并将其存储在leftSwapsCost
中.
最后,我进行代价最低的交换,并在(交换后获得的)不包含交换前原始字符串的第一个和最后一个元素的新字符串newString
上递归调用该函数.
它通过了S="aabb"和S="letelt"的初始测试用例.
但当我提交的时候,它不接受关于S = "eqvvhtcsaaqtqesvvqch"
的答案.这很奇怪,因为it did make the string palindrome in less moves than what LeetCode was expecting.
我得到了以下结果: