본문 바로가기

LeetCode

[LeetCode] - 2129. Capitalize the Title

LeetCode는 프로그래밍 문제를 풀며 코딩 실력을 향상할 수 있는 온라인 플랫폼입니다. 다양한 알고리즘 및 데이터 구조 문제를 제공하며, 면접 대비에 유용합니다. 해당 문제는, LeetCode Problems에서 볼 수 있는 난이도 '쉬움 (Easy)' 단계인 "Capitalize the Title" 문제입니다.

--> https://leetcode.com/problems/capitalize-the-title/description/

 

문제 : 

You are given a string title consisting of one or more words separated by a single space, where each word consists of English letters.

Capitalize the string by changing the capitalization of each word such that :

  • If the length of the word is 1 or 2 letters, change all letters to lowercase.
  • Otherwise, change the first letter to uppercase and the remaining letters to lowercase.

Return the capitalized title.


Example 1 :

Input : title = "capiTalIze tHe titLe"

Output : "Capitalize The Title"

Explanation : Since all the words have a length of at least 3, the first letter of each word is uppercase, and the remaining letters are lowercase.

 

Example 2 :

Input : title = "First leTTeR of EACH Word"

Output : "First Letter of Each Word"

Explanation : The word "of" has length 2, so it is all lowercase.

The remaining words have a length of at least 3, so the first letter of each remaining word is uppercase, and the remaining letters are lowercase.

 

Example 3 :

Input : title = "i lOve leetcode"

Output : "i Love Leetcode"

Explanation : The word "i" has length 1, so it is lowercase.

The remaining words have a length of at least 3, so the first letter of each remaining word is uppercase, and the remaining letters are lowercase.

 

Constraints :

  • 1 <= title.length <= 100
  • title consists of words separated by a single space without any leading or trailing spaces.
  • Each word consists of uppercase and lowercase English letters and is non-empty.

이 문제는 주어진 문자열 title은 하나 이상의 단어로 구성되며, 각 단어는 공백으로 구분되어 있습니다. 각 단어의 대소문자를 다음 규칙에 따라 변경해야 합니다:

  1. 단어의 길이가 1 또는 2인 경우 모든 문자를 소문자로 변환합니다.
  2. 그렇지 않은 경우 첫 글자는 대문자로, 나머지 글자는 소문자로 변환합니다.

변환된 문자열을 반환합니다.

 

class Solution {
    public String capitalizeTitle(String title) {
        String[] words = title.split(" ");
        StringBuilder res = new StringBuilder();

        for (String word : words) {
            if (word.length() <= 2) {
                res.append(word.toLowerCase());
            } else {
                res.append(Character.toUpperCase(word.charAt(0)));
                res.append(word.substring(1).toLowerCase());
            }
            res.append(" ");
        }
        
        // Remove the last appended space
        res.setLength(res.length() - 1);

        return res.toString();
    }
}

 

저는 이런 String 관련 문제가 나오면 항상 String Builder 를 씁니다. 정말로 유용하고 String을 ArrayList로 쓰는

느낌이랄까? 그렇습니다. 정말 유용한 탑재되어 있는 유용한 메소드들도 많고 해서. 이번 코드도 비교적 간단하다고 생각됩니다. 읽으시면 바로 이해가 갈 거라고 믿습니다만, 그래도 제 콘셉트에 맞게 설명도 하나 띄우겠습니다 : 

 

이 코드는 주어진 문자열 title을 변환하여 제목을 올바르게 포맷합니다. 변환 규칙은 단어 길이가 1 또는 2인 경우 모든 문자를 소문자로 변환하고, 그렇지 않은 경우 첫 글자를 대문자로, 나머지 글자를 소문자로 변환하는 것입니다.

 

단어 분리 :

  • split(" ") 메소드를 사용하여 입력 문자열을 공백을 기준으로 분리하여 단어 배열 words를 만듭니다.
  1. 변환된 단어를 저장할 StringBuilder 초기화 :
    • StringBuilder 객체 res를 생성하여 변환된 단어들을 저장합니다.
  2. 단어 변환 :
    • 각 단어를 순회하면서 길이에 따라 변환 규칙을 적용합니다.
    • 단어의 길이가 1 또는 2인 경우 toLowerCase()를 사용하여 소문자로 변환합니다.
    • 그렇지 않은 경우 첫 글자는 Character.toUpperCase()로 대문자로 변환하고, 나머지 글자는 substring(1).toLowerCase()로 소문자로 변환합니다.
    • 변환된 단어를 StringBuilder에 추가하고 단어 사이에 공백을 추가합니다.
  3. 마지막 공백 제거 :
    • 마지막 단어 뒤에 추가된 공백을 제거하기 위해 setLength(res.length() - 1)를 사용하여 StringBuilder의 길이를 줄입니다.
  4. 결과 반환 :
    • 변환된 문자열을 반환합니다.
  • 시간 복잡도 : O(n)
    • 입력 문자열의 길이를 n이라고 할 때, 문자열을 분리하고 각 단어를 변환하는 과정은 문자열의 길이에 비례합니다. 따라서 시간 복잡도는 O(n)입니다.
  • 공간 복잡도 : O(n)
    • 분리된 단어들을 저장하기 위한 배열과 변환된 문자열을 저장하기 위한 StringBuilder가 필요하므로 공간 복잡도는 O(n)입니다.

저는 그와중에 저보다 더 나은 코드를 쓴 사람은 어떻게 썼을까 궁금해서 한 분 찾았습니다. 그분의 코드도 공유해 드리고, 그분의 코드도 같이 설명해 보겠습니다 : 

class Solution {
    public String capitalizeTitle(String title) {
        if(title.length()<3){
            return title.toLowerCase();
        }
      char[] ch=title.toCharArray();
      if(ch.length>2 && !Character.isWhitespace(ch[1]) && !Character.isWhitespace(ch[2]) && ch[0]>='a'&& ch[0]<='z'){
        ch[0]-=32;

      }
      else if(ch[0]>='A'&& ch[0]<='Z' && (Character.isWhitespace(ch[1]) || Character.isWhitespace(ch[2]))){
        ch[0]+=32;
      }
      for(int i=1;i<ch.length;i++){
        if(Character.isWhitespace(ch[i-1]) && i<ch.length-2 && !Character.isWhitespace(ch[i+1]) && !Character.isWhitespace(ch[i+2])){
            if(ch[i]>='a'&& ch[i]<='z'){
                ch[i]-=32;
            }

        }
        else{
            if(ch[i]>='A'&& ch[i]<='Z'){
                ch[i]+=32;
            }
        }
      } 
      return new String(ch); 
    }
}
// 21ecb54 유저의 코드

 

이 분은 저와 다르게 StringBuilder 클래스를 쓰지 않고 날것 그대로를 쓰신 상남/여자입니다. 

 

짧은 문자열 처리 :

    • 문자열 길이가 3 미만인 경우 전체 문자열을 소문자로 변환하여 반환합니다.
  1. 문자 배열 초기화 :
    • 문자열 title을 문자 배열 ch로 변환합니다.
  2. 첫 번째 문자 처리 :
    • 문자열의 첫 문자가 대문자일지 소문자일지를 결정합니다. 첫 두 글자가 단어인지 아닌지를 기준으로 판단합니다.
    • 첫 문자가 소문자이고, 두 번째 및 세 번째 문자가 공백이 아니면 첫 문자를 대문자로 변환합니다.
    • 첫 문자가 대문자이고, 두 번째 또는 세 번째 문자가 공백이면 첫 문자를 소문자로 변환합니다.
  3. 나머지 문자 처리 :
    • 나머지 문자는 이전 문자가 공백인지에 따라 대소문자를 결정합니다.
    • 이전 문자가 공백이면, 현재 문자와 다음 두 문자가 단어인지 판단하여 대문자로 변환합니다.
    • 그렇지 않으면 소문자로 변환합니다.
  4. 결과 반환 :
    • 변환된 문자 배열을 문자열로 변환하여 반환합니다.

이 분은 ASCII 코드 특징을 이용하셨고, character 배열을 사용하셨습니다. 시간, 공간 복잡도는 제 코드와 동일합니다만, 더 혀율작인 코드를 쓰셨습니다. 하나, 전 그래도 제 코드가 더 읽기 쉽고 이해하기 쉽다고 생각됩니다. 여러분들의 생각은 어떤지 궁금합니다.