3355 - Zero Array Transformation I
info
- 문제 보기: 3355 - Zero Array Transformation I
- 소요 시간: 18분 42초
- 풀이 언어:
java
- 체감 난이도: 3️⃣
- 리뷰 횟수: ✅
풀이 키워드
스포주의
누적합
풀이 코드
info
- 메모리: 95560 KB
- 시간: 3 ms
class Solution {
public boolean isZeroArray(int[] nums, int[][] queries) {
int[] diff = new int[nums.length+2];
for (int[] q : queries) {
++diff[q[0]];
--diff[q[1]+1];
}
if (diff[0] < nums[0]) return false;
for (int i = 1; i < nums.length; ++i) {
diff[i] = diff[i] + diff[i-1];
if (diff[i] < nums[i]) return false;
}
return true;
}
}
풀이 해설
대충 생각하면 문제 그대로 query 구간을 1씩 감산해서 판단하는 방식이 있다.
하지만 범위를 따졌을 때 이어서 해당 시간복잡도는 TLE이므로
prefix sum을 이용하여 효율적으로 처리해주어야 한다.
🌌 무지성 풀이 로직 설명
- query의 연산 정보를 기록할
nums.length + 1
길이의diff
배열을 생성한다. - query가 a ~ b 구간이라면
diff[a]
는 1 더하고,diff[b+1]
는 1 뺀다. - diff를 순회하며 이전 칸과 합하고, 해당 합이 대응되는
nums
칸보다 작으면false
를 리턴한다.
🧩 Difference Array
Difference Array는 누적합을 이용하여 연산 처리를 압축하는 자료구조이다.
예를 들어 0짜리 배열에서 구간을 연산해가며 nums의 값에 도달하는지 확인한다고 했을 때,
query가 {1, 3} 이면
0 1 2 3 4
[0, 1, 1, 1, 0, ...]
이런식으로 해당 구간의 칸 하나하나에 가산이 들어가야 할 것이다.
하지만 누적합을 이용하면 일일이 가산하지 않고 어느 구간부터 가산을 얼마나 해야 하는지
구간의 시작점만 마킹해서 이를 최적화할 수 있다.
구간의 끝 직후 지점에는 가산 표시를 돌려놔야하므로 -1 처리한다.
0 1 2 3 4
[0, 1, 0, 0, -1, ...]
따라서 이렇게 시작점과 끝점만 마킹해놓으면 풀이 로직 3번에서 앞 칸과 합하는 과정을 통해
[0, 1, 1, 1, 0, ...]
다시 요렇게 복원된다.
결과적으로 시간복잡도는 가 된다.