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 또는 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를 만듭니다.
- 변환된 단어를 저장할 StringBuilder 초기화 :
- StringBuilder 객체 res를 생성하여 변환된 단어들을 저장합니다.
- 단어 변환 :
- 각 단어를 순회하면서 길이에 따라 변환 규칙을 적용합니다.
- 단어의 길이가 1 또는 2인 경우 toLowerCase()를 사용하여 소문자로 변환합니다.
- 그렇지 않은 경우 첫 글자는 Character.toUpperCase()로 대문자로 변환하고, 나머지 글자는 substring(1).toLowerCase()로 소문자로 변환합니다.
- 변환된 단어를 StringBuilder에 추가하고 단어 사이에 공백을 추가합니다.
- 마지막 공백 제거 :
- 마지막 단어 뒤에 추가된 공백을 제거하기 위해 setLength(res.length() - 1)를 사용하여 StringBuilder의 길이를 줄입니다.
- 결과 반환 :
- 변환된 문자열을 반환합니다.
- 시간 복잡도 : 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 미만인 경우 전체 문자열을 소문자로 변환하여 반환합니다.
- 문자 배열 초기화 :
- 문자열 title을 문자 배열 ch로 변환합니다.
- 첫 번째 문자 처리 :
- 문자열의 첫 문자가 대문자일지 소문자일지를 결정합니다. 첫 두 글자가 단어인지 아닌지를 기준으로 판단합니다.
- 첫 문자가 소문자이고, 두 번째 및 세 번째 문자가 공백이 아니면 첫 문자를 대문자로 변환합니다.
- 첫 문자가 대문자이고, 두 번째 또는 세 번째 문자가 공백이면 첫 문자를 소문자로 변환합니다.
- 나머지 문자 처리 :
- 나머지 문자는 이전 문자가 공백인지에 따라 대소문자를 결정합니다.
- 이전 문자가 공백이면, 현재 문자와 다음 두 문자가 단어인지 판단하여 대문자로 변환합니다.
- 그렇지 않으면 소문자로 변환합니다.
- 결과 반환 :
- 변환된 문자 배열을 문자열로 변환하여 반환합니다.
이 분은 ASCII 코드 특징을 이용하셨고, character 배열을 사용하셨습니다. 시간, 공간 복잡도는 제 코드와 동일합니다만, 더 혀율작인 코드를 쓰셨습니다. 하나, 전 그래도 제 코드가 더 읽기 쉽고 이해하기 쉽다고 생각됩니다. 여러분들의 생각은 어떤지 궁금합니다.
'LeetCode' 카테고리의 다른 글
[LeetCode] - 2351. First Letter to Appear Twice (0) | 2024.07.31 |
---|---|
[LeetCode] - 1837. Sum of Digits in Base K (0) | 2024.07.31 |
[LeetCode] - 2169. Count Operations to Obtain Zero (0) | 2024.07.31 |
[LeetCode] - 2239. Find Closest Number to Zero (0) | 2024.07.31 |
[LeetCode] - 1796. Second Largest Digit in a String (0) | 2024.07.31 |