3가지를 고르는 것이므로 완전탐색하면 당연히 시간초과..
하나를 고정시켜 놓은 후에 투포인터를 이용해서 2개를 고르는 아이디어까지는 생각했는데
반례 케이스를 고려하지 못해서 힘들게 푼 문제다 ㅜㅜ
아래 블로그를 참고해서 아이디어를 얻었다
https://skdltm117.tistory.com/71
정렬 후 -> 투포인터(start, end)를 사용해서 합이 0이 되는 값을 고르면 되는데
여기서 주의해야 할 사항은
같은 값이 여러개인 경우 3가지 조건에 맞춰서 경우의 수를 세주는 것이다!
맨 처음 오답 풀이로 하면 같은 값이 여러개인 경우를 정확히 카운팅 할 수 없다.
1) start, end 같은 값이 여러개인 경우
2) start 같은 값이 여러개인 경우
3) end 같은 값이 여러개인 경우
반례)
8
-10 5 5 5 5 5 5 5
Answer: 21
출력: 6
[오답 풀이]
import java.io.*;
import java.util.*;
public class Main {
static int solve(int start, int end, int key, int[] arr){
int cnt = 0;
while(start<end){
int sum = arr[start]+arr[end];
if(sum==key) {
cnt++;
start++;
}
else if(sum>key){
end--;
}else {
start++;
}
}
return cnt;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
StringTokenizer st = new StringTokenizer(br.readLine());
int[] arr = new int[N];
for(int i=0;i<N;i++){
arr[i] = Integer.parseInt(st.nextToken());
}
Arrays.sort(arr);
int cnt = 0;
for (int i = 0; i < N-1; i++) {
cnt += solve(i + 1, N - 1, arr[i] * -1, arr);
}
System.out.println(cnt);
}
}
위의 답에는 다음과 같은 문제가 있다
-sum==key인 경우 경우의 수를 나누지 않음
- else if~else 문으로 인해 시간초과 발생...
sum==key인 경우에도 인덱스를 바꿔줘야 하기 때문에
기존 방식대로 하려면 sum==key인 경우에도 start++를 추가해주거나
아래 코드처럼 if~else로 한번에 인덱스를 처리해줘야 함..
[정답 풀이]
import java.io.*;
import java.util.*;
public class Main {
static int comb(int n){
return n*(n-1)/2;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
StringTokenizer st = new StringTokenizer(br.readLine());
int[] arr = new int[N];
for(int i=0;i<N;i++){
arr[i] = Integer.parseInt(st.nextToken());
}
Arrays.sort(arr);
long cnt = 0L;
for (int i = 0; i < N-1; i++) {
int start = i+1;
int end = N-1;
int key = arr[i]*-1;
if(arr[i]>0)
break;
while(start<end){
int sCnt = 1;
int eCnt = 1;
int sum = arr[start]+arr[end];
if(sum==key) {
if(arr[start]==arr[end]){
cnt += comb(end-start+1);
break;
}
while(start+1<end && arr[start]==arr[start+1]){
sCnt++;
start++;
}
while(start<end-1 && arr[end]==arr[end-1]){
eCnt++;
end--;
}
cnt += sCnt * eCnt;
}
if(sum>key)
end--;
else
start++;
}
}
System.out.println(cnt);
}
}
'스터디 > Algorithm' 카테고리의 다른 글
[프로그래머스스쿨] 상품을 구매한 회원 비율 구하기 oracle (2) | 2024.09.19 |
---|---|
[백준] 암벽 등반 2412 java -bfs (1) | 2024.09.16 |
[백준] 수들의 합2 2003 java - 투포인터 (1) | 2024.09.10 |
[백준] ABCDE 13923 java - dfs (1) | 2024.08.21 |
[백준] 퇴사2 15486 java - dp (3) | 2024.06.20 |