행운의 숫자(Lucky Number)란?
행운의 숫자(Lucky Number)는 행렬(matrix)에서 자신이 속한 행(row)의 최솟값이면서 동시에 자신이 속한 열(column)의 최댓값인 원소를 뜻합니다.
즉, 어떤 원소가 '행에서는 가장 작고, 열에서는 가장 크다'는 두 조건을 모두 충족할 때 그 원소를 행운의 숫자라고 부릅니다.
문제 정의
정수로 이루어진 2차원 배열을 입력받아, 배열 내부에 존재하는 모든 행운의 숫자를 찾아 새로운 배열로 만들어 반환하는 JavaScript 함수를 작성해야 합니다. 만약 행운의 숫자가 하나도 없다면 빈 배열([])을 반환하면 됩니다.
입력 예시
다음과 같은 2차원 배열이 주어졌다고 가정해 보겠습니다.
const arr = [
[5, 3, 7, 3],
[4, 2, 67, 2],
[2, 32, 7, 4],
[2, 9, 45, 23]
];각 행의 최솟값은 차례대로 3, 2, 2, 2입니다. 그러나 이 값들이 놓인 열에서 최댓값이 되는 경우는 하나도 없습니다. 따라서 기대되는 출력은 아래와 같이 빈 배열입니다.
const output = [];
구현 코드
const arr = [
[5, 3, 7, 3],
[4, 2, 67, 2],
[2, 32, 7, 4],
[2, 9, 45, 23]
];
const luckyNumbers = (arr = []) => {
const column = arr.length;
for(let c = 0; c < column; c++){
let minRow = Math.min(...arr[c]);
let pos = arr[c].indexOf(minRow);
if(minRow === arr[c][pos]){
let tmpMaxColumn = arr[c][pos];
for(let j = 0; j < column; j++){
if(arr[j][pos] > tmpMaxColumn){
tmpMaxColumn = arr[j][pos];
break;
}
}
if(tmpMaxColumn === minRow){
return [tmpMaxColumn];
}
}
};
return [];
};
console.log(luckyNumbers(arr));코드 동작 원리
- 행의 최솟값 찾기: Math.min()과 스프레드 연산자(...)를 사용해 각 행의 최솟값(minRow)을 구하고, indexOf()로 해당 값이 위치한 인덱스(pos)를 알아냅니다.
- 같은 열의 값들과 비교: 찾아낸 위치(pos)와 같은 열에 있는 모든 원소를 순회하며 현재 값보다 큰 값이 있는지 확인합니다. 더 큰 값을 발견하면 반복을 즉시 중단합니다.
- 조건 판정: 열 전체를 검사한 뒤에도 tmpMaxColumn이 여전히 minRow와 같다면, 그 원소는 행의 최솟값이면서 열의 최댓값임이 확인된 것이므로 행운의 숫자입니다.
- 결과 반환: 행운의 숫자를 발견하면 해당 값을 담은 배열을 반환하고, 끝까지 찾지 못했다면 빈 배열을 반환합니다.
참고 사항
위 구현은 행렬이 정사각형(n×n)이라는 가정 하에 arr.length를 행과 열의 길이로 함께 사용합니다. 또한 첫 번째 행운의 숫자를 발견하는 즉시 결과를 반환하므로, 여러 개가 존재할 경우 나머지는 무시됩니다. 모든 행운의 숫자를 수집하려면 return 대신 결과 배열에 push하는 방식으로 수정하면 됩니다. 이 알고리즘의 시간 복잡도는 n×n 행렬 기준 O(n²)입니다.
실행 결과
코드를 실행하면 콘솔에 다음과 같이 출력됩니다.
[]
예제 배열에는 행의 최솟값이면서 열의 최댓값인 원소가 존재하지 않기 때문에 빈 배열이 출력됩니다.