You are given a string s
consisting only of lowercase English letters.
In one move, you can select any two adjacent characters of s
and swap them.
Return the minimum number of moves needed to make s
a palindrome.
Note that the input will be generated such that s
can always be converted to a palindrome.
Example 1:
Input: s = "aabb" Output: 2 Explanation: We can obtain two palindromes from s, "abba" and "baab". - We can obtain "abba" from s in 2 moves: "aabb" -> "abab" -> "abba". - We can obtain "baab" from s in 2 moves: "aabb" -> "abab" -> "baab". Thus, the minimum number of moves needed to make s a palindrome is 2.
Example 2:
Input: s = "letelt" Output: 2 Explanation: One of the palindromes we can obtain from s in 2 moves is "lettel". One of the ways we can obtain it is "letelt" -> "letetl" -> "lettel". Other palindromes such as "tleelt" can also be obtained in 2 moves. It can be shown that it is not possible to obtain a palindrome in less than 2 moves.
Constraints:
1 <= s.length <= 2000
s
consists only of lowercase English letters.s
can be converted to a palindrome using a finite number of moves.
题目:给定一串字符串,每步两个相邻的字符可以呼唤,问最少换多少步可以将字符串变成回文。假设字符串肯定可以变成回文。
思路:双指针+贪心算法。指针i, j最开始指向首位和尾位,如果i位和j位相等,则直接i++,j--。如果不相等,则一直从前找到与s[j]相等和从后找到与s[i]相等的位置。比较哪边需要挪动的步骤少则挪动哪步。
代码:
class Solution {
public:
int minMovesToMakePalindrome(string s) {
int i = 0, j = s.length()-1, res = 0;
while(i < j){
if(s[i] == s[j]){i++; j--;}
else{
int i1 = i+1, j1 = j-1;
while(i1 < j && s[i1] != s[j]) i1++;
while(j1 > i && s[j1] != s[i]) j1--;
if(i1-i <= j-j1){
res += i1-i;
for(int k = i1; k > i; k--){
s[k] = s[k-1];
}
s[i] = s[j];
} else {
res += j - j1;
for(int k = j1; k < j; k++){
s[k] = s[k+1];
}
s[j] = s[i];
}
i++; j--;
}
}
return res;
}
};
time: O(N^2). space:O(1)