[23.02.20] Daily Coding 21

동화·2023년 2월 20일
0

Daily-Coding

목록 보기
11/15
post-thumbnail
  1. 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개 요소를 곱하면 된다.
근데 이걸 조건문으로 쓸 필요 없이 둘 다 구한 다음, 둘을 비교하면 됐었다!

쉬운 방법이 있었지만 그래도 돌아돌아 간 만큼 뿌듯하긴 하다!
하지만 더 쉬운 방법을 늘 생각하는 습관을 가져야겠다..

6개의 댓글

comment-user-thumbnail
2023년 2월 21일

이게 코플릿에 있었던가요??? 기억이 안나요 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 넘나새로운것

답글 달기
comment-user-thumbnail
2023년 2월 22일

알고리즘 못하는 1인으로써🥲 푸신것 만으로도 대단하십니다!!계속 하다보면 멋진 풀이가 나올거에요 화이팅 !!

답글 달기
comment-user-thumbnail
2023년 2월 22일

저도 요즘 알고리즘 기초부터 풀고 있는데, 전에 기억들이 다 사라진 느낌이에요 ,,, ㅋㅋㅋㅋㅋㅋ

답글 달기
comment-user-thumbnail
2023년 2월 23일

ㅋㅋㅋ 저도 이거 저번 주말에 복습했는데 레퍼런스에서 오는 절망감.... ㅠㅠ
필요한 상황만 딱딱 구분하는게 넘나 중요한거같아요 ㅠ

답글 달기
comment-user-thumbnail
2023년 2월 25일

앗.... 코플릿 잊고있었는데 복습해야겠네요.. 안 푼(못 푼..) 문제가 너무 많아요 😭

답글 달기
comment-user-thumbnail
2023년 2월 26일

코플릿 극혐! 어렵기만 하고!! 자세한 강의는 없고!! ㅠㅠ 하기 힘들어서 저는 거의 포기했네요 ㅋㅋㅋ 화이팅입니다.

답글 달기