https://www.acmicpc.net/problem/1253
1253번: 좋다
첫째 줄에는 수의 개수 N(1 ≤ N ≤ 2,000), 두 번째 줄에는 i번째 수를 나타내는 Ai가 N개 주어진다. (|Ai| ≤ 1,000,000,000, Ai는 정수)
www.acmicpc.net
코드설명
투포인터 문제입니다.
문제의 로직입니다.
- 먼저 투포인터를 사용하기 위해 Arrays.sort를 통해 오름차순 정렬합니다.
- start=0, end = N-1 로 선언하여, 처음부터 끝까지 더하기를 통해 가능한지 확인합니다. ( 처음에 end=targetIdx -1 로 선언하여 본인보다 작은 수까지라고 생각했었으나, 생각해보면 start값이 매우 작다면, end값이 arr[targetIdx]의 값보다 훨씬 클 수 있습니다. )
- 본인을 통해 더 한 경우는 포함시키지 않으므로 만약 value 값이 본인의 값과 같다면, targetIdx와 현재 start 혹은 end값을 비교하여 해당 경우는 세지 않고 이동시킵니다.
- 이때 if문의 분기를 모두 세분화합니다. 4-1, 4-2, 4-3 의 과정을 잘못설정한다면, start값이 두번 연산되는 결과가 있을 수 있습니다. (처음에 잘못해놓은 코드는 하단에 정리했습니다. )
- if(value == arr[tagetIdx])
- else if(value > arr[targetIdx]
- else if(value < arr[targetIdx])
예시입력
3 0 0 0 정답 output : 3 false output : 1
코드
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.*; public class Main { public static int T, N; public static int[] arr; public static long answer = 0; public static void main(String[] args) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); N = Integer.parseInt(st.nextToken()); st = new StringTokenizer(br.readLine()); arr = new int[N]; for(int i=0;i<N;i++) { arr[i] = Integer.parseInt(st.nextToken()); } Arrays.sort(arr); for(int i=0;i<N;i++) { twoPointer(i); } System.out.println(answer); } public static void twoPointer(int targetIdx) { int start = 0; int end = N - 1; while(start < end) { int value = arr[start] + arr[end]; if(value == arr[targetIdx]) { //만약 수의 합을 찾았는데, 본인의 값과 + 0 가 더해진 상태라면, 처리하지 않는 조건문을 넣습니다. if(targetIdx == start) { start += 1; }else if(targetIdx == end) { end -= 1; }else { answer += 1; break ; } } else if(value > arr[targetIdx]) { //합이 0보다 크다면 end 를 줄여줍니다. end -= 1; }else if(value < arr[targetIdx]){ //합이 0보다 작다면, start를 증가시킵니다. //3 //0 0 0 //처음에 그냥 else로 한다면, start += 1이 두번 작동되면서 위의 값이 3이 아닌 1이 나옵니다. start += 1; } } } }
오답로직
public static void twoPointer(int targetIdx) { int start = 0; int end = N - 1; while(start < end) { int value = arr[start] + arr[end]; if(value == arr[targetIdx]) { answer += 1; break ; } if(value > arr[targetIdx]) { //합이 0보다 크다면 end 를 줄여줍니다. end -= 1; }else { //합이 0보다 작다면, start를 증가시킵니다. start += 1; } } }
'알고리즘 > Two Pointer' 카테고리의 다른 글
[백준] 2473 세 용액 - 투포인터(Two Pointer) JAVA (0) | 2023.11.13 |
---|---|
[백준] 10942 팰린드롬? - 투포인터 JAVA (0) | 2023.11.01 |
[백준] 2467 용액 - 투포인터 JAVA (0) | 2023.08.10 |
[백준] 2531 회전 초밥 - 슬라이딩 윈도우(Sliding Window) + 투포인터(Two Pointer) + 원형(Circular) + HashMap(해시맵) JAVA (0) | 2023.08.09 |
[백준] 20922 겹치는 건 싫어 - 투 포인터 + HashMap JAVA (0) | 2023.08.09 |