이 문제는 내가 배운 것들을 거의 총동원해서 풀었던 것 같다. 두뇌 풀가동!
처음에는 선분의 길이로만 접근해서 각 선분의 시작점과 끝점만 주구장창 째려보다가 ㅋㅋㅋ
문득 배열로 풀 수 있지 않을까??? 라는 생각이 들어서 시도해보았다.
결과는 pass!
나의 코드
function solution(lines) {
const [s0, e0] = lines[0];
const [s1, e1] = lines[1];
const [s2, e2] = lines[2];
const linesArr = [btw(s0, e0), btw(s1, e1), btw(s2, e2)]
.flat()
.sort((a, b) => a - b)
.filter((v, i, a) => v === a[i + 1]);
return [...new Set(linesArr)].length;
}
function btw(s, e) {
let arr = [];
for (let i = s; i < e; i++) {
arr.push(i);
}
return arr;
}
각 선분마다 대응되는 배열을 만들었는데, 선분의 시작점과 끝점 사이의 정수들을 전부 집어넣은 배열이다. 이 배열을 만들기 위해 btw이라는 함수를 바깥에 선언하고 for문을 돌렸다.
btw 함수에 각 선분의 시작점과 끝점을 인자로 전달할 때 구조분해 할당을 사용하여 가독성을 높였다.
이렇게 나온 3개 배열의 길이는 대응되는 각 선분의 길이가 된다.
3개의 배열을 하나의 빈 배열에 몽땅 넣어버리고 flat을 적용하면 여기서 2번 이상 나오는 숫자는 중복되는 구간이 있다는 의미이다.
따라서 오름차순 정렬하고, filter를 사용하여 2번 이상 등장한 원소들만 남긴다.
마지막으로 중복을 제거하면 중복되는 구간의 길이 반환 완료!
그런데 좀 더 간결하고 직관적인 풀이를 보게 되어 가져와봤다.
다른 풀이
function solution(lines) {
let line = new Array(200).fill(0);
lines.forEach(([a, b]) => {
for (; a < b; a++) line[a + 100]++;
});
return line.reduce((s, v) => (v > 1 ? s + 1 : s), 0);
}
우선 0만 200개 들어있는 배열을 하나 선언해준다. 문제의 제한사항이 -100 ≤ a < b ≤ 100 이기 때문이다.
그리고 lines에 들어있는 3개 원소 배열을 하나씩 돌면서(forEach), 시작점이 끝점과 같아질 때까지 시작점+100번째 인덱스부터 1씩 증가시킨다.
결과적으로 1보다 커진 원소들은 2개 이상의 선분이 겹치는 구간이라는 뜻이므로, 1보다 큰 값을 가지고 있는 숫자들만 더한다. (reduce 사용)