[Gold III] 두 배열의 합 - 2143
성능 요약
메모리: 112696 KB, 시간: 556 ms
❌ 접근 방법. 완탐
➡️ 해당 풀이법의 시간 복잡도 :
당연히 시간복잡도 초과
⭕ 접근 방법. Map을 이용해 누적합 저장하여 빠르게 조회
👇 Map을 이용해 배열의 누적합을 빠르게 조회하는 것은 아래 문제를 리뷰하며 자세히 기록해 두었다.
2015번 수들의 합 4
Map에 저장 해야 할 것은 key : 부분합으로 나올 수 있는 값
, value : 부분합을 key로 가지는 부분배열의 개수
Map을 통해 저장하면 누적합으로 같은 값을 가지는 배열의 개수를 알아낼 수 있다.
➡️ 해당 풀이법의 시간 복잡도 :
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.StringTokenizer;
public class Main_2143 {
static long T; // 목표 합
static int n; // 배열 A의 크기
static int m; // 배열 B의 크기
static long sumA[]; // 배열 A의 누적합
static long sumB[]; // 배열 B의 누적합
static HashMap<Long, Long> mapA; // 배열 A의 부분합과 그 등장 횟수를 저장하는 맵
static HashMap<Long, Long> mapB; // 배열 B의 부분합과 그 등장 횟수를 저장하는 맵
static long cnt; // 결과로 출력할 쌍의 개수
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
T = Long.parseLong(br.readLine());
n = Integer.parseInt(br.readLine());
// 배열 A에서 누적합 구하면서 가능한 부분합의 개수 구하기
sumA = new long[n + 1];
mapA = new HashMap<>();
StringTokenizer st = new StringTokenizer(br.readLine());
for (int j = 1; j <= n; j++) {
sumA[j] = sumA[j - 1] + Long.parseLong(st.nextToken());
for (int i = 0; i < j; i++) {
// 배열 A에서 i~j의 부분합을 키로 가지는 맵이 있다면 그 값을 반환해서 +1하고
// 없다면 0(default)를 반환해서 +1 해라.
mapA.put(sumA[j] - sumA[i], mapA.getOrDefault(sumA[j] - sumA[i], 0L) + 1);
}
}
// 배열 B에서 누적합 구하면서 가능한 부분합의 개수 구하기
m = Integer.parseInt(br.readLine());
sumB = new long[m + 1];
mapB = new HashMap<>();
st = new StringTokenizer(br.readLine());
for (int j = 1; j <= m; j++) {
sumB[j] = sumB[j - 1] + Long.parseLong(st.nextToken());
for (int i = 0; i < j; i++) {
// 배열 B에서 i~j의 부분합을 키로 가지는 맵이 있다면 그 값을 반환해서 +1하고
// 없다면 0(default)를 반환해서 +1 해라.
mapB.put(sumB[j] - sumB[i], mapB.getOrDefault(sumB[j] - sumB[i], 0L) + 1);
}
}
// mapA의 키 순회
for (long key : mapA.keySet()) {
// mapB에 T - (map의 key(부분합))을 key로 가진다면
if (mapB.containsKey(T - key)) {
// 해당 부분합이 몇 번 등장하는지를 계산하고 cnt에 더해준다.
cnt += mapA.get(key) * mapB.get(T - key);
}
}
// 결과 출력
System.out.println(cnt);
}
}