[Programmers] #181921 - 배열 만들기 2 [Java][C++][Python]
l부터 r까지 정수를 순회하며 0과 5로만 이루어진 수를 걸러내는 문제.
[Programmers] #181921 - 배열 만들기 2 [Java][C++][Python]
1. 아이디어
l부터 r까지의 정수를 하나씩 확인하며 각 자리수가 전부 0 또는 5로만 이루어졌는지 판별한다. 판별 함수는 숫자를 10으로 나눈 나머지를 확인하는 과정을 자리수가 다 없어질 때까지 반복하다가, 0도 5도 아닌 자리가 하나라도 나오면 그 즉시 false를 반환하고 그렇지 않으면 true를 반환한다. 조건을 만족하는 수를 오름차순으로 모으고, 하나도 없으면 -1을 담은 배열을 대신 반환한다.
2. 복잡도
| 접근 | 시간 | 공간 |
|---|---|---|
| 풀이 | $O(N \log R)$ | $O(N)$ |
($N$ = l부터 r까지의 정수 개수, $\log R$ = r의 자리수)
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 (func(i)) list.add(i);
}
if (list.isEmpty()) return new int[]{-1};
return list.stream().mapToInt(Integer::intValue).toArray();
}
static boolean func(int x) {
while (x > 0) {
int r = x % 10;
if (r != 0 && r != 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 func(int x) {
while (x > 0) {
int r = x % 10;
if (r != 0 && r != 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 (func(i)) v.push_back(i);
}
if (v.empty()) return {-1};
return v;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
def func(x):
while x > 0:
r = x % 10
if r != 0 and r != 5:
return False
x //= 10
return True
def solution(l, r):
ans = [x for x in range(l, r + 1) if func(x)]
return ans if ans else [-1]
참고
$[l, r]$ 전체를 순회하며 0과 5로만 이루어진 수를 걸러내는 대신, 그런 수를 직접 구성하는 방법도 있다. $r \le 1{,}000{,}000$이라 최대 7자리인데, 첫 자리는 반드시 5(선행 0 불가)이고 나머지 자리는 0 또는 5 중 하나이므로 자릿수 $k$일 때 만들 수 있는 수는 $2^{k-1}$개, 1~7자리를 다 더해도 127개뿐이다. 이 127개를 BFS/재귀로 생성한 뒤 $[l, r]$ 범위만 걸러내면 순회량이 최대 100만에서 127로 줄어든다.
This post is licensed under CC BY 4.0 by the author.