두 개 뽑아서 더하기

kihunism·2022년 1월 27일
0

codingtest 포스트는 절대 절대 다른 사람의 코드를 따라 쓴 것이 아니며, 내가 직접 문제를 푼 것이다. 오직 내 손으로 푼 것만 포스팅 한다.

문제 출처
https://programmers.co.kr/learn/courses/30/lessons/68644
프로그래머스 > 코딩 테스트 연습 > 월간 코드 챌린지 시즌1 > 두 개 뽑아서 더하기

문제 설명

정수 배열 numbers가 주어집니다. numbers에서 서로 다른 인덱스에 있는 두 개의 수를 뽑아 더해서 만들 수 있는 모든 수를 배열에 오름차순으로 담아 return 하도록 solution 함수를 완성해주세요.

제한사항

  • numbers의 길이는 2 이상 100 이하 입니다.
  • numbers의 모든 수는 0 이상 100 이하입니다.

입출력 예시

#1
numbers : [2, 1, 3, 4, 1]
result : [2, 3, 4, 5, 6, 7]
#2
numbers : [5, 0, 2, 7]
result : [2, 5, 7, 9, 12]

입출력 예 설명

입출력 예 #1

  • 2 = 1 + 1
  • 3 = 2 + 1
  • 4 = 1 + 3
  • 5 = 1 + 4 = 2 + 3
  • 6 = 2 + 4
  • 7 = 3 + 4
  • 따라서 [2, 3, 4, 5, 6, 7]을 반환해야 합니다.

나의 풀이

function solution(numbers) {
//     입력 받은 배열 깊은 복사
//     원배열 numbers를 변형시키지 않고 문제를 해결하기 위함
    const copyNumbers = [...numbers]
    
//     이중 for loop을 쓰면 문제가 바로 풀릴 거라고 생각했지만 for문을 많이 쓰는 것은 지양해야 한다고 생각해서 재귀를 선택
    function sumArrayFunc(numbers) {
//         일단, 나의 알고리즘은 배열에서 크기가 2인 부분집합을 모두 골라내어 더하는 것

//         1. 더한 값을 중복에 상관없이 그냥 새로운 배열에 넣는다. 
//         2. 중복을 제거하고 오름차순으로 정렬한다.
        
//         배열의 무조건 첫번째 원소이다.
        let leftPivot = 0
//         첫번째 원소와 더해지는 값이다. 
        let rightPivot = leftPivot + 1
//         일단 더한 값을 모두 중복, 오름차순에 상관 없이 모두 넣을 배열
        let tempReturnValue = []
        
//         배열을 앞의 원소를 하나씩 제거하면서 재귀가 진행되는데 계속 잘려나가서 크기가 2가 되면 자를 수 있지만 나의 알고리즘에 위배 되기 때문에
//         2개가 되면 그 2개를 합하고 배열에 넣고 재귀를 끝낸다.
        if(numbers.length === 2) {
            return [...tempReturnValue, numbers[leftPivot] + numbers[rightPivot]]
        }    
    
//         재귀가 진행중인 코드
//         앞의 값은 고정이며, 오른쪽 인덱스 값이 1씩 증가하여 더하고, 오른쪽 피봇이 제일 끝에가면 for loop은 종료
        for(let i = 0; i < numbers.length - 1; i++) {
            tempReturnValue = [...tempReturnValue, numbers[leftPivot] + numbers[rightPivot]]
            rightPivot++
        }
//         배열의 앞 원소 1개 제거
        numbers.splice(0, 1)
//         배열 재귀
        return [...tempReturnValue, [...sumArrayFunc(numbers)]]
    }
//     재귀 함수를 실행시키고 결과값을 저장
    let returnValue = sumArrayFunc(copyNumbers)
    
//     배열의 중첩이 되었는데 중첩배열을 제거하고 깊이가 1인 일반배열로 변환
    const flatArrayFunc = (arr, depth) => {
        return arr.flat(depth)
    }
    returnValue = flatArrayFunc(returnValue, Infinity)
    
//     set을 이용하여 중복제거 (set은 집합이다. (집합은 중복 허용X -> 중학교 수학개념))
    const set = new Set(returnValue)
//     중복을 제거한 것을 다시 배열에 대입(선언)
    let answer = [...set]
//     오름차순으로 정렬 후 반환
    return answer.sort((a, b) => a - b)
}

profile
Code Occulter

0개의 댓글