문제 설명
n개의 음이 아닌 정수가 있습니다. 이 수를 적절히 더하거나 빼서 타겟 넘버를 만들려고 합니다. 예를 들어 [1, 1, 1, 1, 1]로 숫자 3을 만들려면 다음 다섯 방법을 쓸 수 있습니다.
-1+1+1+1+1 = 3 +1-1+1+1+1 = 3 +1+1-1+1+1 = 3 +1+1+1-1+1 = 3 +1+1+1+1-1 = 3
사용할 수 있는 숫자가 담긴 배열 numbers, 타겟 넘버 target이 매개변수로 주어질 때 숫자를 적절히 더하고 빼서 타겟 넘버를 만드는 방법의 수를 return 하도록 solution 함수를 작성해주세요.
제한사항
- 주어지는 숫자의 개수는 2개 이상 20개 이하입니다.
- 각 숫자는 1 이상 50 이하인 자연수입니다.
- 타겟 넘버는 1 이상 1000 이하인 자연수입니다.
입출력 예
numbers | target | return |
[1, 1, 1, 1, 1] | 3 | 5 |
입출력 예 설명
문제에 나온 예와 같습니다.
🍟 나의 풀이
cnt=0
def solution(numbers, target):
def dp(ans, i, target):
global cnt
leng = len(numbers)
if leng == i: # 인덱스 한도
if ans == target :
cnt+=1
return
dp(ans + numbers[i], i + 1, target)
dp(ans - numbers[i], i + 1, target)
dp(0, 0, target)
return cnt
재귀호출을 이용한 dfs 풀이
dp(값, 인덱스, 타겟넘버)이다. dp가 아니라 dfs인데 함수명 잘못 지음 ㅋㅋ
재귀호출할 때 인덱스 값을 1씩 늘린다.
인덱스가 리스트 numbers 길이와 같고, 값 ans가 target과 같으면 타겟을 만드는 방법의 수 cnt를 증가시킨다.
answer=0
def solution(numbers, target) :
global answer
answer=0
def DFS(idx, target, value) : # 인덱스, 목표값, 계산값
global answer
N=len(numbers)
if (idx == N and target == value) : # 끝까지, 타겟이랑 같으면
answer+=1
return
if(idx == N) : # 끝까지만
return
DFS(idx+1, target, value+numbers[idx])
DFS(idx+1, target, value-numbers[idx])
DFS(0, target, 0)
return answer
다른 사람 풀이 참고하여 완성
global은 함수 밖 전역변수를 쓸 수 있게 한다.
class Solution {
public int solution(int[] numbers, int target) {
answer = 0;
dfs(1, target, numbers[0], numbers);
dfs(1, target, -numbers[0], numbers);
return answer;
}
int answer;
public void dfs(int v, int target, int sum, int[] numbers){ // 인덱스, 타겟 넘버, 합계, 배열
if (v==numbers.length){
if(sum == target){
answer++;
}
return;
}
dfs(v+1, target, sum+numbers[v], numbers);
dfs(v+1, target, sum-numbers[v], numbers);
}
}
재귀호출을 이용한 dfs 풀이
dfs 함수를 호출할 때 numbers의 0번째 인덱스 값을 넣어줬기 때문에 인덱스 v는 1을 줘야한다.
인덱스가 배열을 초과하면 return한다. 타겟 넘버가 되면 정답 answer을 1 증가시킨다.
🍗 다른 사람 풀이
def solution(numbers, target): # 사용할 수 있는 숫자들, 타겟
if not numbers and target == 0 :
return 1
elif not numbers :
return 0
else :
return solution(numbers[1:], target-numbers[0])+solution(numbers[1:], target+numbers[0])
재귀를 효과적으로 사용한 코드
from itertools import product
def solution(numbers, target): # 사용할 수 있는 숫자들, 타겟
l=[(x, -x) for x in numbers]
s=list(map(sum, product(*l)))
return s.count(target)
product는 곱집합 원리다.
answer=0
def DFS(idx, numbers, target, value) :
global answer
N=len(numbers)
if (idx == N and target == value) : # 끝까지, 타겟이랑 같으면
answer+=1
return
if(idx == N) : # 끝까지만
return
DFS(idx+1, numbers, target, value+numbers[idx])
DFS(idx+1, numbers, target, value-numbers[idx])
def solution(numbers, target) :
global answer
DFS(0, numbers, target, 0)
return answer
dfs를 이용한 풀이
// https://velog.io/@jaesika/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-DFS-%ED%83%80%EA%B2%9F%EB%84%98%EB%B2%84
class Solution {
public int solution(int[] numbers, int target) {
int answer=0;
answer=bfs(numbers, target, numbers[0], 1)+bfs(numbers, target, -numbers[0], 1);
return answer;
}
public int bfs(int[] numbers, int target, int sum, int i){
if (i == numbers.length){
if(sum == target){
return 1;
}else{
return 0;
}
}
int result=0;
result+=bfs(numbers, target, sum+numbers[i], i+1);
result+=bfs(numbers, target, sum-numbers[i], i+1);
return result;
}
}
dfs인데 왜 bfs라고 한거지?!
문제 출처 👉 프로그래머스
'coding test' 카테고리의 다른 글
[파이썬, Java] 신규 아이디 추천 (0) | 2021.04.26 |
---|---|
[파이썬, Java] 위장 (0) | 2021.04.23 |
[파이썬, Java] 모의고사 (0) | 2021.04.23 |
[파이썬, Java] K번째수 (0) | 2021.04.23 |
[파이썬, Java] 완주하지 못한 선수 (0) | 2021.04.22 |