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.
출처 : https://leetcode.com/problems/minimum-number-of-moves-to-make-palindrome/description/
풀이
function minMovesToMakePalindrome(s: string) {
let res = 0;
let a = s.split("");
while(a.length > 1) {
let i = a.indexOf(a[a.length - 1]);
if(i === a.length - 1) {
res += Math.floor(i/2);
} else {
res += i;
// Splicing to remove the found character
a.splice(i, 1);
}
// Popping to remove the end character
a.pop();
}
return res;
};
문자열을 팰린드롬으로 만들기 위해 필요한 최소 이동 횟수를 계산하는 함수
팰린드롬은 앞에서 읽으나 뒤에서 읽으나 동일한 문자열을 의미
코드 설명
- 변수 초기화:
- res는 이동 횟수를 저장하는 변수
- a는 입력 문자열 s를 문자 배열로 변환한 것
- 반복문:
- while(a.length > 1) 루프를 통해 배열 a의 길이가 1보다 큰 동안 반복
- 배열의 길이가 1이면 더 이상 비교할 필요가 없으므로 종료
- 문자 찾기:
- let i = a.indexOf(a[a.length - 1])는 현재 배열의 마지막 문자와 같은 문자의 인덱스를 찾음
- 인덱스 확인:
- if(i === a.length - 1) 조건을 통해 찾은 문자가 배열의 마지막 문자와 같은지 확인
- 같다면, 해당 문자가 이미 맞는 위치에 있으므로 이동 횟수는 Math.floor(i/2)로 계산.
- 이는 중간에 있는 문자가 서로 맞춰지는 경우를 고려한 것
- 문자 제거:
- 만약 찾은 문자가 배열의 마지막 문자와 다르다면, res에 i를 더하고, a.splice(i, 1)을 통해 찾은 문자를 배열에서 제거.
- 이후 a.pop()으로 마지막 문자를 제거
- 결과 반환:
- 최종적으로 이동 횟수를 담고 있는 res를 반환
예시 s = "letelt"
초기 설정
- 입력 문자열 s = "letelt"
- res를 0으로 초기화
- 문자열을 문자 배열로 나눔: a = ['l', 'e', 't', 'e', 'l', 't'].
첫 번째 반복
- 배열 상태: ['l', 'e', 't', 'e', 'l', 't']
- 마지막 문자인 't'를 확인. 배열에서 첫 번째 위치를 찾음
- i = a.indexOf('t') → i = 2 (첫 번째 't'의 인덱스).
- i가 a.length - 1 (5)와 같지 않으므로, res에 i를 더함
- res += i → res = 0 + 2 = 2.
- 찾은 문자를 제거
- a.splice(2, 1) → a는 ['l', 'e', 'e', 'l', 't'].
- 마지막 문자를 제거
- a.pop() → a는 ['l', 'e', 'e', 'l'].
두 번째 반복
- 배열 상태: ['l', 'e', 'e', 'l']
- 마지막 문자인 'l'을 확인
- i = a.indexOf('l') → i = 0.
- i가 a.length - 1과 같지 않으므로 res에 i를 더함
- res += i → res = 2 + 0 = 2.
- 찾은 문자를 제거
- a.splice(0, 1) → a는 ['e', 'e', 'l']
- 마지막 문자를 제거
- a.pop() → a는 ['e', 'e']
세 번째 반복
- 배열 상태: ['e', 'e']
- 마지막 문자인 'e'을 확인
- i = a.indexOf('e') → i = 0.
- i가 a.length - 1과 같지 않으므로 res에 i를 더함
- res += i → res = 2 + 0 = 2.
- 찾은 문자를 제거
- a.splice(0, 1) → a는 ['e']
- 마지막 문자를 제거
- a.pop() → a는 [].
종료
- 이제 배열 a가 비었으므로 반복이 종료.
- 최종 결과인 res는 2
'LeetCode' 카테고리의 다른 글
| 1368. Minimum Cost to Make at Least One Valid Path in a Grid / TypeScript (0) | 2024.09.28 |
|---|---|
| 736. Parse Lisp Expression / TypeScript (4) | 2024.09.24 |
| 1487. Making File Names Unique / TypeScript (1) | 2024.09.18 |
| 2762. Continuous Subarrays / TypeScript (1) | 2024.09.16 |
| 452. Minimum Number of Arrows to Burst Balloons / TypeScript (1) | 2024.09.12 |