[Programmers] #181921 - 배열 만들기 2 [Java][C++][Python]
[Programmers] #181921 - 배열 만들기 2 [Java][C++][Python]
1. 아이디어
l부터 r까지의 정수를 전부 하나씩 확인하며 각 자리가 전부 0 또는 5인지 판별하면 된다. 0도 5도 아닌 자리를 하나라도 만나면 그 수는 제외하고, 모든 자리가 조건을 만족하는 수만 오름차순으로 모았다.
2. 복잡도
| 접근 | 시간 | 공간 |
|---|---|---|
| 풀이 | $O(N \times D)$ | $O(K)$ |
($N$ = r - l + 1, $D$ = r의 자릿수 $\approx \log_{10} r$, $K$ = 결과 배열의 길이)
3. 코드
풀이 [Java][C++][Python]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.util.*;
class Solution {
public int[] solution(int l, int r) {
List<Integer> list = new ArrayList<>();
for (int i = l; i <= r; i++) {
if (hasOnly0And5(i)) list.add(i);
}
if (list.isEmpty()) return new int[]{-1};
return list.stream().mapToInt(Integer::intValue).toArray();
}
static boolean hasOnly0And5(int x) {
while (x > 0) {
int d = x % 10;
if (d != 0 && d != 5) return false;
x /= 10;
}
return true;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <bits/stdc++.h>
using namespace std;
bool has_only_0_and_5(int x) {
while (x > 0) {
int d = x % 10;
if (d != 0 && d != 5) return false;
x /= 10;
}
return true;
}
vector<int> solution(int l, int r) {
vector<int> v;
for (int i = l; i <= r; i++) {
if (has_only_0_and_5(i)) v.push_back(i);
}
if (v.empty()) return {-1};
return v;
}
1
2
3
4
5
6
7
def has_only_0_and_5(x):
return all(c in "05" for c in str(x))
def solution(l, r):
ans = [x for x in range(l, r + 1) if has_only_0_and_5(x)]
return ans if ans else [-1]
참고
$[l, r]$ 전체를 순회하며 0과 5로만 이루어진 수를 걸러내는 대신, 그런 수를 직접 구성하는 방법도 있다. $r \le 1{,}000{,}000$이고 7자리인 해당 수는 5000000 이상이라 범위 밖이므로 최대 6자리다. 첫 자리는 반드시 5(선행 0 불가)이고 나머지 자리는 0 또는 5 중 하나이므로 자릿수 $k$일 때 만들 수 있는 수는 $2^{k-1}$개, 1~6자리를 다 더해도 63개뿐이다. 이 63개를 BFS/재귀로 생성한 뒤 $[l, r]$ 범위만 걸러내면 순회량이 최대 100만에서 63으로 줄어든다.
This post is licensed under CC BY 4.0 by the author.