2025. 6. 13. 16:09ㆍ카테고리 없음
문제 분석
1. 두큐 queue1, queue2에서 pop + insert = 1회 작업으로 각 큐의 합을 같게 만드는 최소 작업 수를 구하는 문제
2. pop은 맨 앞, insert는 맨 뒤에 수행
3. 큐는 한 방향으로만 pop, insert 가능
4. 방법이 없으면 -1 리턴
queue1 = [3, 2, 7, 2]
queue2 = [4, 6, 5, 1]
queue1의 합 = 14
queue2의 합 = 16
전체합 = 30 -> 반으로 나눈 15가 목표임
queue1의 합을 14 -> 15로 올리고, queue2의 합을 16 -> 15로 줄이는 방향으로 원소를 이동시켜야함.
주의 사항
브루트 포스 접근 방식으로하면 배열 크기가 최대 300000이기에 불가능
int형의 범위를 넘어가니 long타입 사용해야함
알고리즘 방식
목표: queue1, queue2의 합을 같게 만드는 최소 pop + insert 횟수 계산하기
-> 두 큐를 합쳐서 같은 합의 두 파트로 나누는 최소 이동 시뮬레이션
구현 방법
주어진 두 큐를 이어서 슬라이딩 윈도우 방식으로 알고리즘을 구현해 주었습니다.
슬라이딩 윈도우로 구현하기 위해서는 두 큐를 합쳐서 구현을 해줘야합니다.
// 큐4개를 이은 배열 선언(그래야 슬라이딩 윈도우로 접근 가능)
long[] arr = new long[n*4];
큐 4개를 이어줘야 슬라이딩 윈도우같이 한쪽에서 빼고 한쪽에서 넣어주는 방식이 가능합니다.
// 선언해준 배열에 두 큐 넣기
for(int i = 0; i< n; i++) {
arr[i] = queue1[i];
arr[i + n] = queue2[i];
arr[2*n + i] = queue1[i];
arr[3*n + i] = queue2[i];
// 총합 구해주기 위해 계산
total += queue1[i] + queue2[i];
}
그 후 선언한 배열에 두 큐를 넣어줍니다.
이때 만약 총합이 짝수가 아니라면 -1를 리턴해야하므로(두 큐의 합이 같아질 수 없음) 예외처리를 진행해줍니다.
// 만약 총합이 짝수가 아니면 두 큐의 합이 같게 될수 없으므로 예외처리
if(total % 2 != 0) {
return -1;
}
그 후 우리의 목적은 두 큐의 합이 같은거니까 총 합의 절반을 target으로 잡아준후 시작점을0, 끝나는점을 n이라고 잡아줍니다
그리고 이 한 큐에서의 총 합을 구해줍니다.
long target = total/2;
long currentSum = 0;
int start = 0;
int end = n;
for(int i = 0; i<n; i++) {
currentSum += queue1[i];
}
그 후 답인 count를 기준으로 while문을 통해 end지점이 배열의 끝 지점까지 될때까지 돌려주며 안에서 슬라이딩 윈도우 기법으로
판별해주며 구현해주었습니다.
int count = 0;
int maxOperation = n*3;
while(start <= end && end < arr.length && count <= maxOperation) {
if(currentSum == target) {
return count;
} else if (currentSum < target) {
currentSum += arr[end];
end++;
} else {
currentSum -= arr[start];
start++;
}
count++;
}
최종 코드
class Solution {
public int solution(int[] queue1, int[] queue2) {
int n = queue1.length;
long total = 0;
// 큐4개를 이은 배열 선언(그래야 슬라이딩 윈도우로 접근 가능)
long[] arr = new long[n*4];
// 선언해준 배열에 두 큐 넣기
for(int i = 0; i< n; i++) {
arr[i] = queue1[i];
arr[i + n] = queue2[i];
arr[2*n + i] = queue1[i];
arr[3*n + i] = queue2[i];
// 총합 구해주기 위해 계산
total += queue1[i] + queue2[i];
}
// 만약 총합이 짝수가 아니면 두 큐의 합이 같게 될수 없으므로 예외처리
if(total % 2 != 0) {
return -1;
}
long target = total/2;
long currentSum = 0;
int start = 0;
int end = n;
for(int i = 0; i<n; i++) {
currentSum += queue1[i];
}
int count = 0;
int maxOperation = n*3;
while(start <= end && end < arr.length && count <= maxOperation) {
if(currentSum == target) {
return count;
} else if (currentSum < target) {
currentSum += arr[end];
end++;
} else {
currentSum -= arr[start];
start++;
}
count++;
}
return -1;
}
}