- largestProductOfThree
정수를 요소로 갖는 배열을 입력받아 3개의 요소를 곱해 나올 수 있는 최대값을 리턴해야 합니다.
섹션3들어 급격히 어려워진 난이도에 오함마로 한대 맞은 기분.. ㅎ_ㅎ
섹션2부터 다시 시작하게 된 데일리코딩.
일단 처음에 생각했던 것은, 음수와 0이 섞여있으니 이걸 주의해야겠다 싶었던 거였음.
// 배열 중 (절댓값이) 가장 큰 수 3개?
// 음수는 짝수 개여야 함.
// 3개 중에 0은 없어야 함.
let arr = [-1, 8, 0, -134, -44]
arr.map(Math.abs) = [1, 8, 0, 134, 44]
arr.map(Math.abs).sort() = [0, 1, 134, 44, 8]
let plus = arr.map(Math.abs)
plus.sort()= [0, 1, 134, 44, 8]
일단 테스트 해봤던 방법인데.. 처음에 134가 먼저 나왔는지 이해가 안되었었다
알고보니 문자열 정렬 방법이라, 숫자를 문자열로 바꾸어주어야 한다는 것.
그래서 sort() 에 함수를 추가해주어야 함.
이걸 아직도 헷갈려하는 자 ㅎ_ㅎ
arr2.sort(function (a, b) {
return a - b;
}); // [0, 1, 8, 44, 134]
그리고 .slice(-3)으로 뒤에 세 개 잘라주고..
그 세 개를 곱해준다
근데 이렇게 진행하면 문제가 생긴다.
만약에 큰 수 세 개를 곱했을 때, 원래 음수였던 애가 하나였다면 얘는 가장 큰 수가 아니라 가장 작은 수가 될 것임..
그니까 만약 바뀐 배열이 [0, 1, 8, 44, 134]
근데 여기서 -8 하나라면 진짜 제일 작은 수가 되는 것.. 여기서 절댓값을 벗겨줘봤자 소용이 없다 그건 없는 수니깐..
그래서 초반에 배열을 절댓값으로 배열은 하되, 배열자체에서 숫자는 건들지 않게 함.
let plusArr2 = arr.sort((a, b) => Math.abs(a) - Math.abs(b))
그리고 이제 음수와 양수를 나눠서
경우의 수를 추가해주었다. (여기선 b-a로 만듦, 즉 내림차순)
let negative = sorted.filter(e => e < 0);
let positive = sorted.filter(e => e >= 0);
그리고 (그 전에) reduce 함수로 모든 수를 곱하는 함수를 만듦.
arr3 은 배열 요소가 3개인 배열!
productOfThree = function(arr3) {
let largestProduct = arr3.reduce((acc, cur) => {
return acc * cur;
}, 1);
return largestProduct;
};
그리고 이제 음수 개수가 0일 땐, 양수 배열의 앞에서 3개를 잘라 배열로 만들고,
양수 개수가 0일 땐, 음수 배열의 뒤에서 3개를 잘라 배열로 만들어 곱함.
그리고 또 음수 배열에서 절댓값이 양수 배열 중 가장 큰 수(positive[0]) 를 비교한 배열을 하나 더 추가.
근데 처음에 negative.filter(e => Math.abs(e) >= positive[0])
이렇게만 했더니 나중에는 문제가 생겨서 positive[1]
추가
주절 주절 말은 많았지만..
const largestProductOfThree = function (arr) {
productOfThree = function(arr3) {
let largestProduct = arr3.reduce((acc, cur) => {
return acc * cur;
}, 1);
return largestProduct;
};
const sorted = arr.sort((a, b) => Math.abs(b) - Math.abs(a))
let negative = sorted.filter(e => e < 0);
let positive = sorted.filter(e => e >= 0);
if (negative.length === 0) {
return productOfThree(positive.slice(0, 3));
} else if (positive.length === 0) {
return productOfThree(negative.slice(-3));
} else {
let absNegative = negative.filter(
e => Math.abs(e) >= positive[0] || positive[1]
);
if (absNegative.length >= 2) {
let arr3 = [absNegative[0], absNegative[1], positive[0]];
return productOfThree(arr3);
} else if (absNegative.length <= 1){
if (positive.length === 1){
let arr3 = [negative[0], negative[1], positive[0]]
return productOfThree(arr3)
} else if (positive.length > 1)
return productOfThree(positive.slice(0, 3));
}
}
};
이렇게 복잡하고 열심히 풀었으나 레퍼런스는 단 4줄로 끝났다 ^_^
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);
};
우선 오름차순으로 정렬하고,
음수가 있다면 뒤에 음수 2개를 곱하면 양수가 되고, 거기에 배열의 맨 끝(가장 큰 수!)을 곱하면 된다.
음수가 없다면 맨 끝 3개 요소를 곱하면 된다.
근데 이걸 조건문으로 쓸 필요 없이 둘 다 구한 다음, 둘을 비교하면 됐었다!
쉬운 방법이 있었지만 그래도 돌아돌아 간 만큼 뿌듯하긴 하다!
하지만 더 쉬운 방법을 늘 생각하는 습관을 가져야겠다..
이게 코플릿에 있었던가요??? 기억이 안나요 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 넘나새로운것