Post

[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.