문제 링크
https://school.programmers.co.kr/learn/courses/30/lessons/42895
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
코딩테스트 연습 > 동적계획법(Dynamic Programming) > N으로 표현
문제 설명
아래와 같이 5와 사칙연산만으로 12를 표현할 수 있습니다.
12 = 5 + 5 + (5 / 5) + (5 / 5)
12 = 55 / 5 + 5 / 5
12 = (55 + 5) / 5
5를 사용한 횟수는 각각 6,5,4 입니다. 그리고 이중 가장 작은 경우는 4입니다.
이처럼 숫자 N과 number가 주어질 때, N과 사칙연산만 사용해서 표현 할 수 있는 방법 중 N 사용횟수의 최솟값을 return 하도록 solution 함수를 작성하세요.
제한사항
- N은 1 이상 9 이하입니다.
- number는 1 이상 32,000 이하입니다.
- 수식에는 괄호와 사칙연산만 가능하며 나누기 연산에서 나머지는 무시합니다.
- 최솟값이 8보다 크면 -1을 return 합니다.
입출력 예
N | number | return |
5 | 12 | 4 |
2 | 11 | 3 |
입출력 예 설명
예제 #1
문제에 나온 예와 같습니다.
예제 #2
11 = 22 / 2와 같이 2를 3번만 사용하여 표현할 수 있습니다.
나의 코드
import java.util.*;
class Solution {
public int solution(int N, int number) {
int answer = -1;
ArrayList<HashSet<Integer>> list = new ArrayList<>();
for(int i=0; i<10; i++) {
list.add(new HashSet<>());
}
for(int i=1; i<10; i++) {
HashSet<Integer> set = list.get(i);
set.add(Integer.parseInt(String.valueOf(N).repeat(i)));
for(int j=1; j<i; j++) {
HashSet<Integer> set1 = list.get(j);
HashSet<Integer> set2 = list.get(i-j);
for(int s1 : set1) {
for(int s2 : set2) {
set.add(s1 + s2);
set.add(s1 * s2);
set.add(s1 - s2);
if(s2 != 0)
set.add(s1 / s2);
}
}
}
if(set.contains(number)) {
answer = i;
break;
}
}
return answer;
}
}
풀이
- N을 8개를 사용해도 number를 구하지 못하면 -1을 반환하므로 answer를 -1로 초기화 한다.
- 각 인덱스에 Set을 가지는 ArrayList를 생성한다.
- ArrayList의 각 인덱스 i에 있는 Set에는 N을 i 개를 사용하여 만들 수 있는 수들이 담겨진다.
- 1부터 9까지 for문을 돌면서 우선 N을 i개만큼 연속으로된 수를 담는다.
(예를들어 N이 5이고 i가 1이면 5, i가 2이면 55, i가 3이면 555, i가 8이면 55555555) - 그리고 나머지 만들 수 있는 수들을 담기 위해 j를 1부터 i - 1까지 for문을 돌면서 ArrayList에서 j인덱스의 Set을 가져와 set1에 저장하고 ArrayList에서 (i - j)인덱스의 Set을 가져와 set2에 저장한 후에 set1과 set2를 이중 for each문을 이용해 각각 모든 수끼리 + , *, - 연산을 진행하고 나누는 수가 0이 아니라면 / 연산도 진행하여 ArrayList의 해당 i 인덱스의 Set에 담는다. (숫자의 순서가 바뀌면 연산의 결과가 달라지는 연산이 있으므로 모두 진행한다. 각 Set에 담긴 숫자들은 해당 숫자를 구하기 위해 괄호를 치고 먼저 연산을 진행한 것과 같다)
- 예를 들어 N이 5라면 다음과 같이 j와 i - j에 해당하는 Set을 가져와 모두 연산하고 담는다.
i가 1일 때는 5를 추가한 후 for문은 넘어가고
i가 2일 때는 55 추가 , (j = 1, i - j = 1)
i가 3일 때는 555 추가 , (j = 1, i - j = 2) , (i = 2 , i - j = 1)
i가 4일 때는 5555 추가 , (j = 1, i - j = 3) , (i = 2 , i - j = 2), (i = 3 , i - j = 1)
i가 5일 때는 55555 추가 , (j = 1, i - j = 4) , (i = 2 , i - j = 3), (i = 3 , i - j = 2), (i = 4 , i - j = 1)
.....
i가 8일 때는 55555555 추가 , (j = 1, i - j = 7) , (i = 2 , i - j = 6), (i = 3 , i - j = 5), (i = 4 , i - j = 4), (j = 5, i - j = 3) , (i = 6 , i - j = 2), (i = 7 , i - j = 1) - 이렇게 각 인덱스에 해당하는 개수만큼 N을 이용하여 모든 값을 구했다면 해당 인덱스의 Set에 number가 포함하는지 확인하고 포함한다면 해당 인덱스가 number를 만들 수 있는 N의 개수의 최솟값이므로 answer에 저장하고 반환하면 된다.
참고 : https://small-stap.tistory.com/65
'Programmers' 카테고리의 다른 글
[프로그래머스 Level.3] 선입 선출 스케줄 (연습문제) (Java) (0) | 2023.04.09 |
---|---|
[프로그래머스 Level.3] 외벽 점검 (2020 KAKAO BLIND RECRUITMENT) (Java) (0) | 2023.04.08 |
[프로그래머스 Level.3] 최적의 행렬 곱셈 (연습문제) (Java) (0) | 2023.04.06 |
[프로그래머스 Level.3] 사라지는 발판 (2022 KAKAO BLIND RECRUITMENT) (Java) (0) | 2023.04.05 |
[프로그래머스 Level.2] 과제 진행하기 (연습 문제) (Java) (0) | 2023.04.04 |