2024. 6. 1. 17:37ㆍ알고리즘/카카오
https://school.programmers.co.kr/learn/courses/30/lessons/64065
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
실행 결과 : 실패
문제를 제대로 분석하지 않으면 돌고 돌아 정말 힘들게 해결하거나 실패하는 문제인 거 같다.
순열을 이용해서 해결하려고 했다. 튜플이 될 수 있는 숫자를 저장해서 순열로 경우의 수를 구한다. 왜냐하면 튜플은 순서를 고려하기 때문이다. 그런데 이렇게 접근하니까 코드가 복잡해지고, 오류가 생겨도 어디서 발생했는지 찾기 힘들었다.
처음 설계한 과정은 다음과 같다.
1. 입력값 s를 포멧팅한다.
- 포멧팅은 다음과 같다. "{{2},{2,1},{2,1,3},{2,1,3,4}}" ➡ [[2], [2, 1], [2,1,3], [2,1,3,4]]
2. 포멧팅한 값을 배열 길이의 순서대로 오름차순 정렬한다.
3. 튜플이 될 수 있는 요소들을 구한다.
- [[2], [2, 1], [2,1,3], [2,1,3,4]] ➡ 1, 2, 3, 4가 튜플의 원소가 될 수 있다.
4. 튜플의 원소를 가지고 순열을 활용해 튜플이 될 수 있는 후보를 구한다.
- 1, 2, 3, 4가 될 수도 있고 2, 3, 4, 1이 될 수도 있다.
5. 튜플이 될 수 있는 후보를 가지고 튜플을 만든다.
- 2, 3, 4, 1이면 [[2], [2,3], [2,3,4], [2,3,4,1]] 이렇게 튜플을 만든다.
6. 포멧팅한 값과 만든 튜플을 비교해본다.
- 요소들의 포함여부를 확인한다.
하지만 6번째 단계에서 계속 오류가 발생했다. 사실 6번째가 아니라 다른 단계에서 문제가 발생했어도 디버깅하기가 정말 힘들었다.
그러나 문제에서 주어진 튜플의 개념을 확실하게 파악한다면 코드는 너무나 간단해진다.
튜플의 원소는 중복되지 않으며, 각 튜플은 다른 튜플의 부분 집합이다.
예를 들어 [[2], [2,3], [2,3,4], [2,3,4,1]] 이라는 집합이 있을 때, [2]는 [2, 3]의 부분집합이고, [2,3]은 [2,3,4]의 부분집합이다.
그렇다면 [2, 3]에서는 [2]에 포함되지 않은 3을, [2,3,4]에서는 [2,3]에 포함되지 않은 4를 ret에 넣어주면 (2, 3, 4, 1)이 튜플이 된다.
function formatArr(s){
const ret = [];
let str = s.replace('{{', "").replace('}}', "").split("},{");
for (let i = 0; i < str.length; i++) ret.push(str[i].split(",").map(Number));
return ret;
}
function solution(s) {
const sArr = formatArr(s);
sArr.sort((a, b) => a.length - b.length); // 길이에 따라 정렬
const ret = [];
const seen = new Set();
sArr.forEach(arr => {
arr.forEach(num => {
if (!seen.has(num)) {
seen.add(num);
ret.push(num);
}
});
});
return ret;
}