정수 배열 arr와 2차원 정수 배열 queries이 주어집니다. queries의 원소는 각각 하나의 query를 나타내며, [s, e, k] 꼴입니다.
각 query마다 순서대로 s ≤ i ≤ e인 모든 i에 대해 k보다 크면서 가장 작은 arr[i]를 찾습니다.
각 쿼리의 순서에 맞게 답을 저장한 배열을 반환하는 solution 함수를 완성해 주세요.
단, 특정 쿼리의 답이 존재하지 않으면 -1을 저장합니다.
1 ≤ arr의 길이 ≤ 1,000
0 ≤ arr의 원소 ≤ 1,000,000
1 ≤ queries의 길이 ≤ 1,000
0 ≤ s ≤ e < arr의 길이
0 ≤ k ≤ 1,000,000
arr | queries | result |
---|---|---|
[0, 1, 2, 4, 3] | [[0, 4, 2],[0, 3, 2],[0, 2, 2]] | [3, 4, -1] |
입출력 예 설명
입출력 예 #1
첫 번째 쿼리의 범위에는0, 1, 2, 4, 3
이 있으며 이 중 2보다 크면서 가장 작은 값은 3입니다.
두 번째 쿼리의 범위에는0, 1, 2, 4
가 있으며 이 중 2보다 크면서 가장 작은 값은 4입니다.
세 번째 쿼리의 범위에는0, 1, 2
가 있으며 여기에는 2보다 큰 값이 없습니다.
따라서[3, 4, -1]
을 return 합니다.
function solution(arr, queries) {
let result = []
queries.forEach(([s,e,k]) => (
result.push(arr.slice(s, e + 1).filter(el => el > k).sort((a,b) => a-b))
))
return result.map((el) => el.length > 0 ? el[0] : -1)
}
이거 분명 day6에 푸는 문제 중 하나인데 난이도가 생각 보다 높아서 깜짝 놀랐다.
결국 다른 사람들의 질문 내용에서 힌트를 확인하면 풀었다..ㅠ
빈 배열인 result를 선언한다.
해단 변수에는 filter로 걸러진 값들이 들어 간다.
queries.forEach(([s,e,k]) => (
result.push(arr.slice(s, e + 1).filter(el => el > k).sort((a,b) => a-b))
))
queries를 forEach를 통해 순환을 한다. 이 때 구조분해 할당으로 넣어 준다. [s,e,k]
[[s,e,k],[s,e,k],[s,e,k]]
처럼 표현된다고 생각하면 된다.
해당 코드는 네 가지로 나눠 볼 수 있다.
arr.slice(s, e + 1)
s기준으로 e만큼 자른 배열을 반환한다.
+1을 한 이유는 문제에서 요구하는 사항을 충족하기 위해서이다.
arr.slice(s, e + 1).filter(el => el > k)
k보다 크면서 가장 작은 arr[i]를 찾습니다.
filter를 통해 조건을 충족하는 배열 요소만 반환한다.
arr.slice(s, e + 1).filter(el => el > k).sort((a,b) => a-b)
2-0번까지 풀었다면 [[4,3],[4],[]]
의 배열을 반환한다.
여기서 최소값을 구해야하는데 이 부분에서 헤맸던 것 같다.
다른 사람들의 질문에서 sort메소드의 힌트를 얻어 해결 할 수 있었다.
a-b
를 한 이유는 sort는 유니코드 기준으로 정렬하기 때문에
원하는 정렬이 안 나올 수 있다. 이때 a-b
를 해줘야한다.
result.push(arr.slice(s, e + 1).filter(el => el > k).sort((a,b) => a-b)
마지막으로 해당 배열을 result에 push한다.
그렇다면 [[3,4],[3],[]]
라는 배열을 얻을 수 있다.
return result.map((el) => el.length > 0 ? el[0] : -1)
map메소드를 사용해 result를 순환하고 만약 el의 길이가 0보다 클 경우(값이 존재할 경우)
배열의 첫번째 값을
그렇지 않을 경우 -1
를 반환한다.
여기서 문제점은
- forEach내부에서 변수를 선언하려고 했으나 에러가 났다.
- 두번째는 마지막 값을 반환할 때
el[0]
보다 다른 방법이 없는지도 궁금하다.
function solution(arr, queries) {
return queries.map(([s, e, k]) => {
let result = -1
for (let i = s; i <= e; i += 1) {
const v = arr[i]
if (v <= k) continue
result = result === -1 ? v : Math.min(result, v)
}
return result
})
}
이분은 처음부터 result에 -1를 할당하고 값이 충족되지 않을 경우 바로 result를 반환하셨다.
그리고 Math.min()
을 사용해 최소값을 구하셨다.
이분 코드를 보니 프로그래머스 코드에서 map, forEach, reduce 등의 메소드 내부에
변수선언을 할 수 있는 것 같다. (그럼 나는 왜 안 된건지...?)
Math.min()
- 주어진 숫자들 중 가장 작은 값을 반환합니다.
- 주어진 숫자들 중 가장 작은 값.
- 만약 적어도 1개 이상의 인자값이 숫자형으로 변환이 불가능 한 경우 이 함수는
NaN
를 반환 합니다.Math.min([value1[, value2[, ...]]])
-출처 : mdn