LeetCode는 프로그래밍 문제를 풀며 코딩 실력을 향상할 수 있는 온라인 플랫폼입니다. 다양한 알고리즘 및 데이터 구조 문제를 제공하며, 면접 대비에 유용합니다. 해당 문제는, LeetCode Problems에서 볼 수 있는 난이도 '쉬움 (Easy)' 단계인 "Largest Odd Number in String" 문제입니다.
--> https://leetcode.com/problems/largest-odd-number-in-string/description/
문제 :
You are given a string num, representing a large integer.
Return the largest-valued odd integer (as a string) that is a non-empty substring of num,
or an empty string "" if no odd integer exists.
A substring is a contiguous sequence of characters within a string.
Example 1 :
Input : num = "52"
Output : "5"
Explanation : The only non-empty substrings are "5", "2", and "52". "5" is the only odd number.
Example 2 :
Input : num = "4206"
Output : ""
Explanation : There are no odd numbers in "4206".
Example 3 :
Input : num = "35427"
Output : "35427"
Explanation : "35427" is already an odd number.
Constraints :
- 1 <= num.length <= 10^5
- num only consists of digits and does not contain any leading zeros.
이 문제는 주어진 문자열 num에서 가장 큰 값의 홀수를 찾는 문제입니다. 이 문제를 해결하기 위해 문자열을 뒤에서부터 순회하면서 홀수를 찾으면 그 위치까지의 모든 문자를 포함하는 서브스트링을 반환하면 됩니다. 이렇게 하면 가장 큰 값의 홀수를 찾을 수 있습니다.
class Solution {
public String largestOddNumber(String num) {
List<Integer> oddIndices = new ArrayList<>();
for (int i = 0; i < num.length(); i++) {
if ((num.charAt(i) - '0') % 2 != 0) {
oddIndices.add(i);
}
}
if (oddIndices.isEmpty()) return "";
Collections.sort(oddIndices);
int lastIndex = oddIndices.get(oddIndices.size() - 1);
return num.substring(0, lastIndex + 1);
}
}
제 첫 코드는 이거였습니다.
주어진 문자열 num에서 가장 큰 값의 홀수를 찾는 문제를 해결합니다. 주어진 접근 방법은 먼저 문자열에서 모든 홀수 인덱스를 찾아 리스트에 저장하고, 가장 큰 인덱스를 사용하여 결과를 반환합니다.
- 홀수 인덱스 저장 :
- List<Integer> oddIndices = new ArrayList<>(); 문장을 사용하여 홀수 인덱스를 저장할 리스트를 초기화합니다.
- for (int i = 0; i < num.length(); i++) { ... } 문장을 사용하여 문자열 num을 순회하면서 각 문자가 홀수인지 확인합니다.
- 홀수인 경우, oddIndices.add(i); 문장을 사용하여 해당 인덱스를 리스트에 추가합니다.
- 홀수 인덱스 확인 :
- if (oddIndices.isEmpty()) return ""; 문장을 사용하여 리스트가 비어있는지 확인합니다. 비어 있으면 문자열에 홀수가 없다는 의미이므로 빈 문자열을 반환합니다.
- 가장 큰 인덱스 사용 :
- Collections.sort(oddIndices); 문장을 사용하여 홀수 인덱스 리스트를 정렬합니다.
- int lastIndex = oddIndices.get(oddIndices.size() - 1); 문장을 사용하여 가장 큰 인덱스를 가져옵니다.
- 결과 반환 :
- return num.substring(0, lastIndex + 1); 문장을 사용하여 가장 큰 홀수 인덱스까지의 서브스트링을 반환합니다.
- 시간 복잡도 : O(n log n)
- 문자열의 길이를 n이라고 할 때, 문자열을 한 번 순회하면서 홀수 인덱스를 찾으므로 O(n) 시간이 소요됩니다.
- 홀수 인덱스 리스트를 정렬하는 데 O(n log n) 시간이 추가로 소요됩니다.
- 따라서 전체 시간 복잡도는 O(n log n)입니다.
- 공간 복잡도 : O(n)
- 모든 홀수 인덱스를 저장하기 위해 리스트 oddIndices를 사용하므로 공간 복잡도는 O(n)입니다.
보시다시피 시간 복잡도 면에서 굉장히 비효율적입니다. 개선해야 할 점이 많습니다.
class Solution {
public String largestOddNumber(String num) {
// Iterate through the string from the end
for (int i = num.length() - 1; i >= 0; i--) {
// Check if the current character is an odd digit
if ((num.charAt(i) - '0') % 2 != 0) {
// Return the substring from the start to the current index (inclusive)
return num.substring(0, i + 1);
}
}
// If no odd digit is found, return an empty string
return "";
}
}
처음 코드에서는 불필요한 Collections.sort() 를 해버렸습니다.
이 코드는 주어진 문자열 num에서 가장 큰 값의 홀수를 찾기 위해 문자열을 끝에서부터 순회하며 첫 번째 홀수를 찾으면 해당 위치까지의 서브스트링을 반환합니다. 이렇게 하면 가장 큰 값의 홀수를 효율적으로 찾을 수 있습니다.
- 문자열을 끝에서부터 순회 :
- for (int i = num.length() - 1; i >= 0; i--) 문장을 사용하여 문자열 num을 끝에서부터 순회합니다.
- 홀수 확인 :
- if ((num.charAt(i) - '0') % 2 != 0) 문장을 사용하여 현재 문자가 홀수인지 확인합니다.
- 문자를 정수로 변환하여 2로 나눈 나머지가 1이면 홀수입니다.
- 결과 반환 :
- 홀수를 찾으면 return num.substring(0, i + 1); 문장을 사용하여 해당 위치까지의 서브스트링을 반환합니다.
- 문자열을 끝까지 순회한 후에도 홀수를 찾지 못하면 return ""; 문장을 사용하여 빈 문자열을 반환합니다.
- 시간 복잡도 : O(n)
- 문자열의 길이를 n이라고 할 때, 문자열을 한 번 순회하므로 시간 복잡도는 O(n)입니다.
- 문자열의 끝에서부터 순회하기 때문에 최대 n번의 비교 연산이 필요합니다.
- 공간 복잡도 : O(1)
- 추가적인 배열이나 리스트를 사용하지 않고, 상수 공간만 사용하므로 공간 복잡도는 O(1)입니다.
- 필요한 공간은 단지 몇 개의 변수(i)를 저장하는 데 사용됩니다.
결론적으로 개선된 코드는 기존 코드에 비해 효율성이 높습니다. 불필요한 리스트와 정렬을 제거함으로써 시간 복잡도는 O(n)으로 줄었고, 공간 복잡도는 O(1)로 최적화되었습니다. 이는 특히 문자열의 길이가 길어질수록 성능 향상에 큰 도움이 됩니다.
'LeetCode' 카테고리의 다른 글
[LeetCode] - 2255. Count Prefixes of a Given String (0) | 2024.07.31 |
---|---|
[LeetCode] - 2185. Counting Words With a Given Prefix (0) | 2024.07.31 |
[LeetCode] - 1920. Build Array from Permutation (0) | 2024.07.31 |
[LeetCode] - 2351. First Letter to Appear Twice (0) | 2024.07.31 |
[LeetCode] - 1837. Sum of Digits in Base K (0) | 2024.07.31 |