이렇게만 보면 감이 안 오지만 입출력 예시를 보면 좀 더 이해가 쉽다.
- let output = largestProductOfThree([2, 1, 3, 7]);
console.log(output); // --> 42 (= 2 3 7)- output = largestProductOfThree([-1, 2, -5, 7]);
console.log(output); // --> 35 (= -1 -5 7)
이 문제는 주의사항이 좀 함정이었던 거 같다. 배열 내 요소에 음수 값도 받을 수 있었던 것!
주의사항
- 입력으로 주어진 배열은 중첩되지 않은 1차원 배열입니다.
- 배열의 요소는 음수와 0을 포함하는 정수입니다.
- 배열의 길이는 3 이상입니다.
0) sort로 정렬
sort메서드로 정렬하면 배열의 끝에서 3번째, 2번째 그리고 마지막 요소만 뽑아서 곱해주면 가장 큰 값들이 모인 것이기 때문에 최대값을 리턴할 수 있을것이라고 생각했다.
1) 배열의 길이가 3개일 때
배열의 길이가 3개일 땐 요소들의 대소를 비교할 것 없이 그냥 다 곱해야하므로 그경우를 일단 조건문으로 만들어 주었다.
2) 배열의 길이가 3개이상이면서 모두 음수일 때
이 경우 배열의 길이가 3개이상면서 배열의 모든 요소들을 더했을때 0보다 작으면 을 조건문으로 설정해주었다.
이렇게 접근해서 나온 코드가 아래와 같았다.
const largestProductOfThree = function (arr) { // TODO: 여기에 코드를 작성합니다. // arr의 요소들을 정렬시키고 뒤에서 세번째 두번째 그리고 마지막을 곱해주면 되지 않을까 let sumArr = arr.reduce((stack, el)=>{ return stack + el; }, 0); let newArr = arr.sort((a, b) => a - b); // 만약 배열의 길이가 3개이고 0을 갖고 있다면 if(arr.length <= 3) { return arr[0]*arr[1]*arr[2] } // 만약 배열의 길이가 3개이고 그 요소들이 모두 음수라면 for(let i=0; i < arr.length; i++ ) { if(arr.length >= 3 && sumArr < 0 ) { return newArr[newArr.length-3]*newArr[newArr.length-2]*newArr[newArr.length-1] } } };
이렇게 접근하면 코드가 쓸데없이 길어지고 배열의 요소 중 부분만 음수일 때의 경우를 거르지 못한다. 그래서 테스크케이스도 9개 중 4개밖에 통과를 못한다. 그래서 확인한 레퍼코드가 훨씬 쉽고 직관적인데다가 효율적이었다.
다른 접근 방법도 sort메서드로 정렬해주되 배열 중 부분적으로 음수가 있어도 가능한 경우였다.
0) sort메서드로 정렬
sort메서드로 정렬하는 건 음수일 때는 해결이 안되지 않나 싶었다. 그러나 음수에서도 해결이 가능하다.
1) 음수들을 2개를 곱하여 큰 수 만들고, 가장 마지막번째 요소(양수 중 가장 큰 수)를 곱함
부분 음수가 있는 상태에서 sort메서드로 정렬하고 나면 배열의 0번째 요소와 1번째요소를 곱해주면 큰값이 나온다.(가장 작은 음수2개를 곱해주면서 값이 큰 양수가 됨) 그리고 가장 마지막 요소는 양수 중에서 가장 큰값이니 단독으로 곱해주면 가장 큰 값이 나온다.
예시)
let arr = [-5, 2, -1, 6, 8]
arr.sort((a,b) => a - b) // [ -5, -1, 2, 6, 8 ]
나는 윗 부분을 놓쳤다ㅠ 토이문제중에선 쉬운 문제인데 좀 아쉽다...ㅠ
3) Math.max()함수 이용
모든 값들이 양수일 때와 부분적으로 음수일 때를 나누어 변수를 설정하고 그 두개의 변수를 Math.max() 함수로 리턴하면 끝.
const largestProductOfThree = function (arr) { const sorted = arr.slice().sort((a, b) => a - b); const len = arr.length; const candi1 = sorted[len - 1] * sorted[len - 2] * sorted[len - 3]; const candi2 = sorted[len - 1] * sorted[0] * sorted[1]; return Math.max(candi1, candi2); };