지식/알고리즘

89일 (917. Reverse Only Letters) String, Character.is()?

매우 강한사람 2023. 12. 18. 16:54

Given a string s, reverse the string according to the following rules:

  • All the characters that are not English letters remain in the same position.
  • All the English letters (lowercase or uppercase) should be reversed.

Return s after reversing it.

 

Example 1:

Input: s = "ab-cd"
Output: "dc-ba"

Example 2:

Input: s = "a-bC-dEf-ghIj"
Output: "j-Ih-gfE-dCba"

Example 3:

Input: s = "Test1ng-Leet=code-Q!"
Output: "Qedo1ct-eeLg=ntse-T!"

 

Constraints:

  • 1 <= s.length <= 100
  • s consists of characters with ASCII values in the range [33, 122].
  • s does not contain '\"' or '\\'.

 

- 접근방법

아스키코드 33~122까지가 문자열 s의 char범위이다.

1. 영소문자(65~90) 영대문자(97~122)에 속하는 경우를 모두 구하여 뒤집어야하고

2. 영소문자(65~90) 영대문자(97~122)에 속하지 않는 경우를 구하여 현재 인덱스를 기억하고 그대로 삽입하여야한다.

 

 

- 코드 (StringBuilder) 1ms

class Solution {
    public String reverseOnlyLetters(String s) {
        StringBuilder stringBuilder = new StringBuilder();
        int n = s.length();

        for(int i = n-1; i >= 0; i--) { // 1
            char ch = s.charAt(i);
            if(Character.isLetter(ch)) stringBuilder.append(ch);
        }


        for(int i = 0; i < n; i++) { // 2
            char ch = s.charAt(i);
            if(!Character.isLetter(ch)) stringBuilder.insert(i,ch);
        }

        return stringBuilder.toString();
    }
}

 

String은 불변의 객체라서 문자열을 수정하기위해 StringBuilder를 사용하였다.

 

 

 

- 코드 (toCharArray()) 0ms

class Solution {
    public String reverseOnlyLetters(String s) {
        char [] arr = s.toCharArray();
        int ptr1 = 0;
        int ptr2 = s.length()-1;

        while(ptr1 < ptr2) { // reverse를 위함
			
            // 1. 양쪽이 문자인 경우 서로 스왑
            if(Character.isLetter(arr[ptr1]) && Character.isLetter(arr[ptr2])) {
                char temp = arr[ptr1]; // swap
                arr[ptr1++] = arr[ptr2];
                arr[ptr2--] = temp;
            }

		// 2. 문자가 아닌 경우 위치는 그대로.
            if(!Character.isLetter(arr[ptr1])) ptr1++; 
            if(!Character.isLetter(arr[ptr2])) ptr2--;

        }

        return new String(arr);
    }
}

 

공간복잡도는 stringBuilder와 비슷하지만 약간 더 빠르다.

 

Character.isLetter() isDigit() 등으로 문자인지 숫자인지 등 판별할 수 있는 메서드를 인지하는 것이 중요하다.

 

위 메서드를 활용하지 못한다면 

if((char >= 65 && char <= 90) || (char >= 97 && char <= 122))

 

영대문자와 영소문자를 포함하고 싶은 경우 위처럼 비효율적으로 작성하여야 하기 때문이다.

 

 

 

 

https://leetcode.com/problems/reverse-only-letters/

 

Reverse Only Letters - LeetCode

Can you solve this real interview question? Reverse Only Letters - Given a string s, reverse the string according to the following rules: * All the characters that are not English letters remain in the same position. * All the English letters (lowercase or

leetcode.com