[LeetCode] Reverse ... a String

코테연습|2024. 9. 17. 12:23

비슷한 두 개의 문제를 풀었다.

 

첫 번째 문제 (Reverse Vowels of a String)

https://leetcode.com/problems/reverse-vowels-of-a-string/description/?envType=study-plan-v2&envId=leetcode-75

Given a string s, reverse only all the vowels in the string and return it.

The vowels are 'a', 'e', 'i', 'o', and 'u', and they can appear in both lower and upper cases, more than once.

 

Example 1:

Input: s = "IceCreAm"

Output: "AceCreIm"

Explanation:

The vowels in s are ['I', 'e', 'e', 'A']. On reversing the vowels, s becomes "AceCreIm".

Example 2:

Input: s = "leetcode"

Output: "leotcede"

 

Constraints:

  • 1 <= s.length <= 3 * 105
  • s consist of printable ASCII characters.

 

주어진 문자열의 모음만 역순으로 재배치하는 문제.

 

문제 풀이

크게 고민할 부분은 없었던 것 같다.

모음인 문자열과 그 문자열의 위치를 각 배열에 저장하고, 문자열을 저장한 배열만 리버스하여 재배치했다.

function reverseVowels(s: string): string {
    const stringArr = s.split(""); // 문자열을 배열로 만든다.
    const vowels = ["a","e","i","o","u"];

    const vowelString = []; // 주어진 String 내에서 모음만 들어갈 배열
    const vowelIndex = []; // 해당 모음의 index 배열

    const isVowel = (str:string) => {
        return vowels.includes(str.toLowerCase())
    }
    
    stringArr.map((str, index)=>{
        if (isVowel(str)){
            // 모음인 문자열과 해당 문자열의 index를 저장
            vowelString.push(str);
            vowelIndex.push(index);
        }
    });
    vowelString.reverse(); // 배열 뒤집기

    vowelString.map((obj, i)=>{
        // 원래 위치에 뒤집어진 모음 문자열을 넣어준다.
        stringArr.splice(vowelIndex[i], 1, obj);
    })

    return stringArr.join("");
};

 

 

다른 풀이

function swap(str: string[], i: number, j: number) {
    const temp = str[i]
    str[i] = str[j]
    str[j] = temp
}

function reverseVowels(s: string): string {
    const sArr = s.split('')
    const vowels = new Set<string>(['a', 'e', 'i', 'o', 'u'])
    
    let p1 = 0
    let p2 = s.length - 1

    while (p1 < p2) {
        if (vowels.has(sArr[p1].toLowerCase()) && vowels.has(sArr[p2].toLowerCase())) {
            swap(sArr, p1, p2)
            p1++
            p2--
            continue
        }
        if (!vowels.has(sArr[p1].toLowerCase())) {
            p1++
        }
        if (!vowels.has(sArr[p2].toLowerCase())) {
            p2--
        }
    }

    return sArr.join('')
};

 

포인터 두 개로 풀이하는 방식(출처)도 흥미로웠다.

앞/뒤에서부터 하나씩 문자를 체크해서 둘 다 모음이면 둘의 자리를 바꾸고,

서로 만날 때까지 모음이 아닌 문자열이 나오면 한 칸씩 전진/후진하는 방식이다. 

 

 

두 번째 문제 (Reverse Words in a String)

https://leetcode.com/problems/reverse-words-in-a-string/?envType=study-plan-v2&envId=leetcode-75

Given an input string s, reverse the order of the words.

word is defined as a sequence of non-space characters. The words in s will be separated by at least one space.

Return a string of the words in reverse order concatenated by a single space.

Note that s may contain leading or trailing spaces or multiple spaces between two words. The returned string should only have a single space separating the words. Do not include any extra spaces.

 

Example 1:

Input: s = "the sky is blue"

Output: "blue is sky the"

Example 2:

Input: s = "  hello world  "

Output: "world hello"

Explanation: Your reversed string should not contain leading or trailing spaces.

Example 3:

Input: s = "a good   example"

Output: "example good a"

Explanation: You need to reduce multiple spaces between two words to a single space in the reversed string.

 

Constraints:

  • 1 <= s.length <= 104
  • s contains English letters (upper-case and lower-case), digits, and spaces ' '.
  • There is at least one word in s.

 

두번째 문제는 비슷하지만 이번에는 어절을 기준으로 뒤집어야 한다는 차이가 있다.

그리고 각 어절 사이에 공백이 몇 개가 있든, 앞 뒤에 몇 개가 있든 다 제외해야 한다는 제약사항이 있다.

 

문제 풀이

function reverseWords(s: string): string {
    const splitted = s.split(" ").filter((str)=>str !== "").reverse();
    return splitted.join(" ");
};

 

이것도 단순히, 띄어쓰기를 기준으로 문자열을 split한 뒤 빈 문자열은 제외하고, 

배열을 리버스한 뒤 띄어쓰기로 join해주는 걸로 풀 수 있었다.

 

다른 풀이

function reverseWords(s: string): string {
  return s.split(' ').reduce((a, c, i) => {
    if (c === '') {
      return a;
    }
    if (a === '') {
      return c;
    }
    return `${c} ${a}`;
  }, '');
}

 

reduce로 접근한 것(출처)도 봤는데, reduce는 잘만 쓰면 참 쉽게 문제를 풀게 해 주는듯하다.

'코테연습' 카테고리의 다른 글

[LeetCode] Increasing Triplet Subsequence  (0) 2024.09.19
[LeetCode] Can Place Flowers  (0) 2024.09.16
[LeetCode] Kids With the Greatest Number of Candies  (0) 2024.09.16

댓글()