타겟 넘버(python)
참고자료
문제 설명
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 |
나의 생각
우선 완전 탐색을 시도해야된다고 생각을 했고, c++의 next_permutation STL이 생각이 났다.
예시를 보니 target을 만들려면 numbers 중 target의 수 만큼의 1은 무조건 필요하다고 느꼈다.
그리고 target 수 만큼 뺀 나머지 1의 갯수의 반은 +1, 나머지 반은 -1로 해서 next_permutation을 적용하면 되겠다.
하지만 python에서의 permutation과 c++ next_permutation은 약간의 차이가 존재했고,
문제를 잘 읽어보니 숫자가 무조건 1인 경우가 아니였다..
솔루션
DP 느낌
for문을 통해서 numbers의 숫자 탐색하고, for문을 통해서 기존 배열에 값에 숫자 값을 더한 값, 뺀 값을 저장하여 빈 배열에 저장 후 기존 배열을 빈 배열로 초기화.
이 경우 기존 배열은 numbers의 각 숫자를 더한 값, 뺀 값의 결과들이 저장되어 있다. 이제 기존 배열에서 target의 값을 카운팅해주면 된다.DFS
(numbers의 index, numbers 리스트, target, numbers[index]값이 더해지거나 뺀 값) 이렇게 4가지 인수가 필요. 시작은 0번째 index, value는 0부터 시작. index가 numbers의 길이(모든 numbers를 다 탐색한 후)일때 그리고 target == value일 때 갯수를 카운팅 후 함수 종료. index가 numbers의 길이(모든 numbers를 다 탐색한 후)일때 그리고 target != value일 때 아무 액션없이 함수 종료. 함수 종료 요건이 안되면 DFS(index + 1, numbers, target, value + numbers[index])를 부름(재귀) DFS(index + 1, numbers, target, value - numbers[index])를 부름(재귀)BFS
queue에 index, value 값으로 초기화
while queue:
를 통해서 queue가 빈 리스트일 때까지 진행
index == len(numbers)
이고target == value
인 경우만 answer += 1을 해주고
index == len(numbers)
인 경우는 아무것도 안함
그 외의 경우는 queue에 (index + 1, value + numbers[index]), (index + 1, value - numbers[index])을 추가
코드
- 첫번째 코드
def solution(numbers, target): answers = [0] for n in numbers: new_answers = [] for a in answers: new_answers.append(a + n) new_answers.append(a - n) answers = new_answers return answers.count(target)
- 두번째 코드
- 갯수를 전역 변수를 설정해서 구해주는 경우.
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
- 갯수를 전역 변수를 설정해서 구해주는 경우.
- 세번째 코드
- 갯수를 지역 변수를 설정해서 구해주는 경우.
def DFS(idx, numbers, target, value): ret = 0 if idx == len(numbers): if target == value: return 1 else: return 0 ret += DFS(idx + 1, numbers, target, value + numbers[idx]) ret += DFS(idx + 1, numbers, target, value - numbers[idx]) return ret
def solution(numbers, target): answer = DFS(0, numbers, target,0) return answer
- 갯수를 지역 변수를 설정해서 구해주는 경우.
- 네번째 코드
- slicing을 활용하고 return에서 갯수를 구해주는 경우.
- solution함수를 재귀 함수로 썼다는 점에서 신기했다.
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])
몰랐던 지식
c++의 next_permutation과 python의 permutations의 차이.
순열을 구하는 것은 맞지만 c++의 nexT_permutation은 중복이 있는 원소의 경우 중복인 경우를 제외하고 순열을 만들어준다.
더 알아볼 지식
stackoverflow를 참고해서 python으로 c++ next_permutation을 구현해보자