문제 설명
선분 3개가 평행하게 놓여 있습니다. 세 선분의 시작과 끝 좌표가 [[start, end], [start, end], [start, end]] 형태로 들어있는 2차원 배열 lines가 매개변수로 주어질 때, 두 개 이상의 선분이 겹치는 부분의 길이를 return 하도록 solution 함수를 완성해보세요.
lines가 [[0, 2], [-3, -1], [-2, 1]]일 때 그림으로 나타내면 다음과 같습니다.
line_2.png
선분이 두 개 이상 겹친 곳은 [-2, -1], [0, 1]로 길이 2만큼 겹쳐있습니다.
제한사항
lines의 길이 = 3
lines의 원소의 길이 = 2
모든 선분은 길이가 1 이상입니다.
lines의 원소는 [a, b] 형태이며, a, b는 각각 선분의 양 끝점 입니다.
-100 ≤ a < b ≤ 100
입출력 예
lines result
[[0, 1], [2, 5], [3, 9]] 2
[[-1, 1], [1, 3], [3, 9]] 0
[[0, 5], [3, 9], [1, 10]] 8
입출력 예 설명
입출력 예 #1
두 번째, 세 번째 선분 [2, 5], [3, 9]가 [3, 5] 구간에 겹쳐있으므로 2를 return 합니다.
입출력 예 #2
겹친 선분이 없으므로 0을 return 합니다.
입출력 예 #3
첫 번째와 두 번째 선분이 [3, 5] 구간에서 겹칩니다.
첫 번째와 세 번째 선분 [1, 5] 구간에서 겹칩니다.
두 번째와 세 번째 선분 [3, 9] 구간에서 겹칩니다.
따라서 [1, 9] 구간에 두 개 이상의 선분이 겹쳐있으므로, 8을 return 합니다.
function solution(lines) {
let new_lines = [];
let overlaps = [];
let answer = 0;
for(let i=0; i<lines.length; i++){
let sum = [];
while(lines[i][0] <= lines[i][1]){
sum.push(lines[i][0]);
lines[i][0] = lines[i][0] + 1
}
new_lines.push(sum);
}
for(let j = 0; j<lines.length; j++){
if(j==0 &&(new_lines[j].filter(x => new_lines[j+2].includes(x))).length >= 2){
overlaps.push(new_lines[j].filter(x => new_lines[j+2].includes(x)))
}
if (j+1 < lines.length && (new_lines[j].filter(x => new_lines[j+1].includes(x))).length >= 2){
overlaps.push(new_lines[j].filter(x => new_lines[j+1].includes(x)));
}
}
if (overlaps.length === 0) {
return 0;
}
let min = Number.POSITIVE_INFINITY;
let max = Number.NEGATIVE_INFINITY;
overlaps.forEach(arr => {
arr.forEach(num => {
min = Math.min(min, num);
max = Math.max(max, num);
});
});
return max - min;
}

각 lines의 요소들의 범위 값을 모두 구한 후, 교집합을 구했다.
그리고 그 중 가장 큰 값과 작은 값의 거리차를 통해 result 값을 구하고자 했다.
하지만 실패.
밑의 코드를 보니 음수가 -100일 때의 예외도 생각해주지 못했다.
정답코드
function solution(lines) {
let answer = 0;
let lineMap = new Array(200); // 선분들이 놓일 공간
lineMap.fill(0);
for (let i = 0; i < 3; i++) {
let left = lines[i][0];
let right = lines[i][1];
for (let j = left; j < right; j++) {
lineMap[j + 100] += 1;
}
}
for (let i in lineMap) {
if (lineMap[i] > 1) {
answer += 1;
}
}
return answer;
}
이 코드는 선분들의 겹치는 부분을 찾는데 사용되는 알고리즘입니다. 선분들은 2차원 배열 lines에 저장되어 있으며, 각 선분은 시작점과 끝점으로 구성된 배열로 표현됩니다.
코드를 단계별로 살펴보면 다음과 같습니다:
선분들을 표시할 lineMap이라는 배열을 초기화합니다. 이 배열의 길이는 200이며, 모든 요소는 0으로 설정됩니다. 이 배열은 선분들이 어떻게 위치하는지 나타내는 역할을 합니다.
lines 배열을 순회하면서 각 선분의 시작점과 끝점을 가져옵니다. 이후 이 두 점 사이에 있는 모든 위치에 대해 lineMap의 해당 위치의 값을 1씩 증가시킵니다. 이를 통해 각 위치에 놓인 선분의 개수를 파악합니다.
lineMap 배열을 순회하면서 각 위치에 놓인 선분의 개수를 확인합니다. 만약 선분의 개수가 1보다 크다면, 이는 선분들이 겹치는 부분을 의미합니다. 이런 겹치는 부분의 개수를 answer에 더합니다.
마지막으로, answer를 반환합니다. answer는 선분들이 겹치는 부분의 개수를 나타냅니다.
참고로, lineMap 배열의 인덱스에 + 100을 하는 이유는 선분의 위치가 음수인 경우를 처리하기 위함입니다. 이렇게 하면, 선분의 위치가 -100에서 100 사이인 경우를 모두 처리할 수 있습니다.
'🗃️javascript > 프로그래머스' 카테고리의 다른 글
안전지대 (0) | 2023.08.31 |
---|---|
평행 (0) | 2023.08.31 |
폰켓몬(Lv.1)[해시의 개념을 생각해보고, 단순히 구현하자] (0) | 2023.06.20 |
K번째수(Lv.1)[sort()는 문자정렬임. 숫자 정렬도 문자열 정렬로 취급] (0) | 2023.06.20 |
n보다 커질 때까지 더하기(Lv.0)[함수 안에 조건달기] (0) | 2023.06.13 |