Coding Test Study/Programmers
[Java] 자릿수 교환을 통한 최댓값 찾기
똑똑한망치
2024. 2. 17. 23:13
728x90
반응형
1. 문제
숫자 num 이 주어졌을 때, 최대 한 번의 자릿수 교환을 통해 최대의 숫자를 만들어 내려고 한다. 즉, 자릿수를 교환하지 않았을 때가 더 큰 숫자일 경우, 원래 숫자를 그대로 출력한다.
2. 입력 설명
- 10 <= num <= 1000000
3. 출력 설명
만들 수 있는 최대의 숫자를 반환
4. 매개변수 형식
num = 43824
5. 반환값 형식
83424
6. 입출력 예시 설명
0번째 인덱스의 숫자 '8' 과 2번째 인덱스의 숫자 '4'의 자릿수를 바꾸었을 때 가장 큰 수가 된다.
7. 힌트
그리디 알고리즘 사용
(1) 해결해야 할 조건들
- 자릿수가 낮아지면서 숫자가 커지는 위치가 있는지 확인한다.
- 만약 숫자가 커지는 위치가 없다면 그 숫자가 가장 큰 숫자이므로 그대로 반환
- ex) 987654321
- 숫자가 커지는 위치가 존재한다면 그 인덱스에 있는 값을 A 라고 가정할 때,
- A보다 높은 자릿수에서 A보다 작은 숫자와 변경해야 하고
- ex) 987658321 일 때, A는 8이고 바꿔줘야 할 수는 7이다.
- A보다 낮은 자릿수에서 A보다 더 큰 수가 있는지 확인해야 한다.
- ex) 987658093 일 때, A인 8 보다 더 큰 9가 뒤에 있기 때문에 9를 A로 선택해야 한다.
- 발견한 A보다 더 큰 숫자이면서도, 더 낮은 자릿수에 있는 수를 A 로 선택해야 한다.
- ex) 987658099 일 때, A 는 1의 자리에 있는 '9'가 A로 선택되어야 한다.
- A보다 높은 자릿수에서 A보다 작은 숫자와 변경해야 하고
8. 코드 구현
class Solution {
public int solution(int num) {
// 각 자릿수에 접근해야 하기 때문에 int를 char[] 로 변환하여 접근한다.
// Brute-force X
// Greedy Algorithm O
final char[] digits = String.valueOf(num).toCharArray();
// index 1 부터 숫자가 커지는 위치가 있는 지 확인
// 시간복잡도 : O(n)
int increaseIdx = -1;
for (int i = 1; i < digits.length; i++) {
if (digits[increaseIdx] > digits[increaseIdx - 1]) {
increaseIdx = i;
break;
}
}
// 일의 자리로 갈수록 작은 숫자를 가지고 있다면,
// 지금이 가장 큰 숫자이므로 그대로 반환
if (increaseIdx == -1) {
return num;
}
// 위에서 찾은 숫자를 기준으로 더 큰 숫자가 있는지 찾는다.
// 크기가 같더라도, 더 낮은 자릿수에 있는 수로 교체한다.
// 즉, 크기가 크면서 가장 낮은 자릿수에 있는 숫자를 찾는다.
// 시간 복잡도 : O(n)
char maxVal = digits[increaseIdx];
int maxIdx = increaseIdx;
for (int i = increaseIdx; i < digits.length; i++) {
if (digits[i] >= maxVal) {
maxVal = digits[i];
maxIdx = i;
}
}
// 큰 자릿수부터 교체할 maxVal 보다 작은 숫자를 찾는다.
// 더 작은 숫자를 발견하면 swap 하고 반환
// 시간복잡도 : O(n)
for (int i = 0; i < increaseIdx; i++) {
if(digits[i] < maxVal) {
digits[maxIdx] = digits[i];
digits[i] = maxVal;
return Integer.parseInt(String.valueOf(digits));
}
}
return num;
}
}
반응형