코딩테스트

[Q03] LargestProductOfThree

HungryOcto 2023. 1. 11. 22:00

1. 문제

정수를 요소로 갖는 배열을 입력받아 3개의 요소를 곱해 나올 수 있는 최대값을 리턴해야 합니다.

1 - 1) 입력

인자 1 : arr

  • number 타입을 요소로 갖는 임의의 배열

1 - 2) 출력

number 타입을 리턴해야 합니다.

1 - 3) 주의사항

입력으로 주어진 배열은 중첩되지 않은 1차원 배열입니다.
배열의 요소는 음수와 0을 포함하는 정수입니다.
배열의 길이는 3 이상입니다.

1 - 4) 입출력 예시

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)

2. 나의 풀이

2 - 1) 코드

제출한 답안

const largestProductOfThree = function (arr) {

    let arrMul = [];
  
    for(let i = 0; i < arr.length-2; i++){
      for(let j = i + 1; j < arr.length-1; j++){
        for(let k = j + 1; k < arr.length; k++){
          arrMul.push(arr[i]*arr[j]*arr[k]);
        }
      }
    }
  
    let result = arrMul[0];
  
    for(let i = 1; i < arrMul.length; i++){
      if(result < arrMul[i]) result = arrMul[i];
    }
  
    return result;
    
  };

 

2 - 2) 코드 + 풀이과정

문제 해결을 위한 아이디어 포함

const largestProductOfThree = function (arr) {
    // TODO: 여기에 코드를 작성합니다.
    // 반복문을 3개 사용하면 되지 않을까?
    // arr[0]*arr[1]*arr[2], arr[0]*arr[1]*arr[3], ..., arr[0]*arr[1]*arr[arr.length-1]
    // arr[0]*arr[2]*arr[3], arr[0]*arr[2]*arr[4], ..., arr[0]*arr[2]*arr[arr.length-1]
    // , ..., arr[0]*arr[arr.length-2]*arr[arr.length-1]
    
    // , ..., arr[arr.length-3]*arr[arr.length-2]*arr[arr.length-1]
  
    let arrMul = [];
  
    for(let i = 0; i < arr.length-2; i++){
      for(let j = i + 1; j < arr.length-1; j++){
        for(let k = j + 1; k < arr.length; k++){
          arrMul.push(arr[i]*arr[j]*arr[k]);
        }
      }
    }
  
    let result = arrMul[0];
  
    // 배열 arrMul에서 가장 큰 요소 찾기
    for(let i = 1; i < arrMul.length; i++){
      if(result < arrMul[i]) result = arrMul[i];
    }
  
    return result;
    
  };

3. 레퍼런스 코드 분석

  const largestProductOfThree = function (arr) {
    // sort() 메서드를 사용, 숫자를 요소로 갖는 배열 arr의 요소들을 오름차순으로 정렬
    // slice() 메서드에 start와 end값을 지정하지 않음 = 0번째 인덱스부터 배열의 끝까지 추출
    // 즉, const sorted = arr.slice().sort((a, b) => a - b); 의 의미는 아래와 같음
    // 배열 arr의 요소들을 숫자의 크기를 기준으로 오름차순으로 정렬한 뒤, 
    // slice()로 arr를 복사하여 새로운 변수 sorted에 할당

    // (굳이 위와 같이 적은 이유 
    // : sort() 메서드의 기본 정렬 순서는 문자열의 유니코드 코드 포인트를 따른다는 점을 잊지 않기 위함)
    // arr.sort(a,b)와 같이 작성하는 경우 숫자 크기 순이 아닌 a, b의 유니코드 순서를 기준으로 배열을 정렬함.
    // 숫자 크기 순으로 정렬하기 위해서는 arr.sort((a, b) => a - b); 와 같이 함수식을 사용해주어야 함.
    
    const sorted = arr.slice().sort((a, b) => a - b);
    const len = arr.length;

    // 구하고자 하는 것 : 배열 내 요소 3개를 곱한 값 중 가장 큰 수를 리턴

    // 오름차순으로 정렬한 배열 sorted의 끝에서부터 순서대로 3개의 수를 곱한 값은 최댓값일 가능성이 있음.
    const candi1 = sorted[len - 1] * sorted[len - 2] * sorted[len - 3];

    // 배열 내 요소에는 음수도 존재함
    // 음수와 음수의 곱은 양수가 되므로
    // 만약 배열 내 요소 중 음수가 2개 이상 존재한다면 
    // 양수 3개의 곱보다 가장 작은 음수 2개와 가장 큰 양수를 곱한 값이 더 클 수도 있음. 

    // 만약 배열 내 요소 중 음수가 2개 이상 존재한다면
    // 오름차순으로 정렬한 배열 sorted의 sorted[0]은 가장 작은 음수, sorted[1]은 두번째로 작은 음수일 것임.
    // 따라서 sorted[0] * sorted[1] * 가장 큰 양수(sorted[len-1])의 결과 또한 최댓값일 가능성이 있음.
    const candi2 = sorted[len - 1] * sorted[0] * sorted[1];

    // Math.max() 함수는 입력값으로 받은 0개 이상의 숫자 중 가장 큰 숫자를 반환함.
    // Math.max() 함수를 사용, candi1과 candi2를 비교하여 중 더 큰 수를 함수의 결과값으로 return함.
    return Math.max(candi1, candi2);
  };

4. 학습 중 궁금해서 찾아본 부분

  • Array.sort()
    • 개념 : sort() 메서드는 배열의 요소를 적절한 위치에 정렬한 후 그 배열을 반환합니다. 정렬은 stable sort가 아닐 수 있습니다. 기본 정렬 순서는 문자열의 유니코드 코드 포인트를 따릅니다. 
    • 주의 : 반환값은 정렬한 배열. 원 배열이 정렬되는 것에 유의. 복사본이 만들어지는 것이 아님. (mutable)
    • 출처 : https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
    • 사용예 : 
// 구문
// arr.sort([compareFunction])

const months = ['March', 'Jan', 'Feb', 'Dec'];
months.sort();
console.log(months);
// expected output: Array ["Dec", "Feb", "Jan", "March"]

const array1 = [1, 30, 4, 21, 100000];
array1.sort();
console.log(array1);
// expected output: Array [1, 100000, 21, 30, 4]

 

  • Array.slice()
    • 개념 : slice() 메서드는 어떤 배열의 begin 부터 end 까지(end 미포함)에 대한 얕은 복사본을 새로운 배열 객체로 반환합니다. 원본 배열은 바뀌지 않습니다.
    • 주의 : end는 포함되지 않음. 원본 배열은 바뀌지 않고 얕은 복사본이 만들어짐(=immutable).
    • 출처 : https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
    • 사용예 :
// 구문
// arr.slice([begin[, end]])

// 구문 해석
// 매개변수 : begin(optional), end(optional)

// begin : 추출 시작점을 지정하는 매개변수
// 음수로 지정하는 경우는 배열 끝에서부터의 위치를 의미
// undefined인 경우 0번 인덱스부터 slice
// begin이 배열의 길이보다 큰 경우, 빈 배열 반환

// end : 추출 종료점을 지정하는 매개변수 (해당 인덱스는 추출에 포함되지 않음)
// 음수로 지정하는 경우는 배열 끝에서부터의 위치를 의미
// undefined인 경우 배열의 끝까지 추출
// end가 배열의 길이보다 크다면, 배열의 끝까지만 slice

// 응용
// arr.slice()와 같이 시작점과 끝점을 설정하지 않는 경우
// arr를 얕은 복사하여 다른 변수에 할당하는 용도로 사용할 수 있음.

// 사용예
const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];

console.log(animals.slice(2));
// expected output: Array ["camel", "duck", "elephant"]

console.log(animals.slice(2, 4));
// expected output: Array ["camel", "duck"]

console.log(animals.slice(1, 5));
// expected output: Array ["bison", "camel", "duck", "elephant"]

console.log(animals.slice(-2));
// expected output: Array ["duck", "elephant"]

console.log(animals.slice(2, -1));
// expected output: Array ["camel", "duck"]

console.log(animals.slice());
// expected output: Array ["ant", "bison", "camel", "duck", "elephant"]

 

※ 추가로 학습하면 좋은 내용 : Array.sort() 메서드의 응용 예

https://developer-talk.tistory.com/73

 

[JavaScript]배열 정렬 sort()

JavaScript에서 배열의 요소들을 정렬하기 위해 sort() 메서드를 사용합니다. sort() 메서드를 사용하면 배열의 요소를 오름차순 또는 내림차순으로 정렬할 수 있으며, 기존 배열의 요소들을 정렬합니

developer-talk.tistory.com


5. 학습 후기

.