문제
https://school.programmers.co.kr/learn/courses/30/lessons/131127
🐍파이썬
def solution(want, number, discount):
answer = 0
#원하는 품목이 모두 있는지 확인
for i, j in zip(want, number):
if j > discount.count(i):
return 0
for k in range(len(discount)-9):
check = 0
for i, j in zip(want, number):
# k ~ k+10일 안에 원하는 품목이 존재하지 않는 경우, k+1 진행
if j > discount[k:k+10].count(i):
check = 0
break
check = 1
answer += check
return answer
1️⃣ zip()을 이용해 discount 전체에 원하는 품목이 모두 있는지 체크하고, 원하는 상품의 재고가 없다면 바로 0을 리턴하여 종료한다.
2️⃣ 행사기간에 원하는 상품을 구매할 수 있다면, 10일 간의 행사기간에 모든 물건을 살 수 있는지 확인한다. discount 배열을 10개씩 끊어서 확인.
3️⃣ 10일 간 물건을 구매할 수 없는 경우 check flag = 0으로 지정한 뒤 break하여 일수를 하루 옮긴 '다음 10일'을 체크한다.
4️⃣ 10일 간 물건을 구매할 수 있는 경우에는 check flag = 1
5️⃣ k+1하기 전, 저장해 둔 체크 플래그 값을 answer 변수에 더한다.(물건을 살 수 있는 경우 1, 살 수 없는 경우 0)
#원하는 품목이 모두 있는지 확인
for i, j in zip(want, number):
if j > discount.count(i):
return 0
이 코드는 없애도 동작이 되기는 하는데, 문제의 테스트 케이스 2번을 보고 우선 넣기는 했다.
시간 복잡도는 때에 따라 달라진다.
다른 풀이 방법
from collections import Counter
def solution(want, number, discount):
answer = 0
dic = {}
for i in range(len(want)):
dic[want[i]] = number[i]
for i in range(len(discount)-9):
if dic == Counter(discount[i:i+10]):
answer += 1
return answer
1️⃣ dic에 {"banana": 3, "rice":2, ...}와 같이 원하는 품목과 갯수를 저장
2️⃣ Counter() 클래스를 사용한 결과값과 dic의 결과값이 동일한 경우 10일간 원하는 물건을 살 수 있다는 뜻이기 때문에 answer += 1
dic과 Counter(discount[0:10])의 값은 아래와 같다.
...
for i in range(len(discount)-9):
# dic = {'banana': 3, 'apple': 2, 'rice': 2, 'pork': 2, 'pot': 1}
# Counter(discount[0:10]) = Counter({'banana': 3, 'apple': 2, 'rice': 2, 'pork': 2, 'pot': 1})
if dic == Counter(discount[i:i+10]):
answer += 1
...
Counter(discount[i:i+10])의 나머지도 동일하게 동작한다.
❗ 참고
Counter() 클래스
중복된 원소가 들어있는 배열을 매개변수로 넘기면 각 원소가 몇 개 들어있는지 저장된 객체를 얻을 수 있다.
Counter(["hi", "hey", "hi", "hi", "hello", "hey"])
// Counter({'hi': 3, 'hey': 2, 'hello': 1})
출처: https://www.daleseo.com/python-collections-counter/
🐥자바스크립트
function solution(want, number, discount) {
var answer = 0;
let dic = {};
for(let i = 0; i < want.length; i++){
dic[want[i]] = number[i];
}
for(let i = 0; i <= discount.length - 10; i++){
let check = 0;
for(let key in dic){
if(dic[key] > discount.slice(i, i+10).filter((el)=> el === key).length){
check = 0;
break;
}
check = 1;
}
answer += check;
}
return answer;
}
파이썬 <다른 풀이 방법>의 dictionary 사용과 스스로 푼 문제의 flag 사용법을 합쳐서 풀어보았다.
for문을 더 많이 돌게 되어 시간 효율성은 좋지 않다...
다른 풀이 방법
function solution(want, number, discount) {
let count = 0;
for (let i = 0; i < discount.length - 9; i++) {
const slice = discount.slice(i, i+10);
let flag = true;
for (let j = 0; j < want.length; j++) {
if (slice.filter(item => item === want[j]).length !== number[j]) {
flag = false;
break;
}
}
if (flag) count += 1;
}
return count;
}
'Problem Solving > 프로그래머스' 카테고리의 다른 글
[프로그래머스 | 파이썬 / 자바스크립트] 소인수분해(코딩테스트 입문/ level 0) (0) | 2023.02.24 |
---|---|
[프로그래머스 | 파이썬 / 자바스크립트] 문자 반복 출력하기(코딩테스트 입문/ level 0) (0) | 2023.02.23 |
[프로그래머스 | 파이썬 / 자바스크립트] 삼각형의 완성조건 (1)(코딩테스트 입문/ level 0) (0) | 2023.02.23 |
[프로그래머스 | 파이썬 / 자바스크립트] 카드 뭉치(연습문제/ level 1) (0) | 2023.02.23 |
[프로그래머스 | 파이썬 / 자바스크립트] 배열 뒤집기(코딩테스트 입문/ level 0) (0) | 2023.02.23 |
[프로그래머스 | 파이썬 / 자바스크립트] 삼각형의 완성조건 (2)(코딩테스트 입문/ level 0) (0) | 2023.02.23 |