일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- leetcode
- 직무면접
- 투포인터
- 삼성 SW역량테스트 기출
- 운영체제
- 다시보기
- Java
- 수학
- 리트코드
- 프로그래머스
- 마곡속눈썹연장
- 포스코
- OS
- 1차면접
- ai/bigdata
- 등촌동속눈썹연장
- 삼성
- 마곡속눈썹펌
- BOJ
- 등촌동속눈썹펌
- 시뮬레이션
- 정렬
- 백준
- 카카오
- 추석트래픽
- 딥러닝
- 알고리즘
- 삼성SW역량테스트
- 코딩테스트
- level2
- Today
- Total
기록하는 습관을 들이자
[ 백준 2470번 두 용액 ] 문제 풀이(Java) - 투 포인터 문제 풀이 본문
투 포인터 문제를 풀어보았습니다.
오랜만에 알고리즘 문제 풀이 포스팅을 진행하는 것 같습니다..ㅋㅋ 앞으로 열심히해야짓..
문제보기
2470번: 두 용액
첫째 줄에는 전체 용액의 수 N이 입력된다. N은 2 이상 100,000 이하이다. 둘째 줄에는 용액의 특성값을 나타내는 N개의 정수가 빈칸을 사이에 두고 주어진다. 이 수들은 모두 -1,000,000,000 이상 1,000,00
www.acmicpc.net
나의 풀이
문제는 간단합니다. 용액의 특성값을 나타내고 있는 배열이 주어진 뒤, 해당 배열에서 두 개의 용액을 합쳤을 때 합친 용액의 특성 값이 0에 가장 가까운 두 용액을 고르면 되는 문제입니다.
가장 쉽게 떠올릴 수 있는 방법으로는 for문 두 개를 이용해서 모든 배열의 쌍에 대해 조사하는 방법이 있습니다. 그런데 이 방법은 안되는 이유가 N의 최대값이 100,000이라서 최대 연산 개수가 O(N^2) == O(10^10)이라서 시간초과가 나게 됩니다...
이전 포스팅에서 시간초과가 날 경우 떠올릴 수 있는 방법으로는
dp
그리디
이분탐색
투포인터
가 있다고 한 적이 있는데요! 여기서는 투 포인터 방법을 이용하도록 하겠습니다.
투 포인터는 start, end 두 개의 포인터를 이용해 조작하는 방법입니다.
먼저, 용액의 특성값이 담긴 배열을 오름차순으로 정렬해준 뒤, start와 end 포인터의 초기값으로 start는 0, end는 배열의 가장 마지막 원소를 가리키게 해줍니다.
시뮬레이션 과정
1. start와 end 포인터가 만날 때까지 반복
- 현재 start와 end 포인터가 가리키는 두 용액의 특성 값 합을 구하고, 결과값 업데이트
- start 포인터를 1 증가시켰을 때와 end 포인터를 1 증가시켰을 때의 값을 비교하여 0에 더 가까운 쪽으로 포인터 값 증가시키기
코드
//백준 2470번 두 용액
//투 포인터 알고리즘
package 백준;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
public class N_2470 {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
int[] A = new int[N];
String[] arr = br.readLine().split(" ");
for (int i = 0; i < N; i++)
A[i] = Integer.parseInt(arr[i]);
Arrays.sort(A);
int start = 0;
int end = A.length - 1;
long result = Integer.MAX_VALUE;
int answer1 = 0;
int answer2 = 0;
while (start != end) {
if (result > Math.abs(A[end] + A[start])) {
result = Math.abs(A[end] + A[start]);
answer1 = A[start];
answer2 = A[end];
}
if (Math.abs(A[start] + A[end - 1]) < Math.abs(A[start + 1] + A[end])) {
end--;
} else {
start++;
}
}
System.out.println(answer1 + " " + answer2);
}
}
'알고리즘 > BOJ' 카테고리의 다른 글
[ 백준 2252번 줄 세우기 ] 문제 풀이(Java) - 위상 정렬 문제 풀이 (0) | 2020.09.29 |
---|---|
[ 백준 16236번 아기 상어 ] 문제 풀이(Java) - 삼성 SW역량테스트 기출 (0) | 2020.05.25 |
[ 백준 5397 키로거 ] 문제 풀이(Java) - 시뮬레이션 문제 (0) | 2020.04.30 |
[ 백준 15685번 드래곤 커브 ] 문제 풀이(Java) - 삼성 SW역량테스트 기출 (0) | 2020.04.29 |
[ 백준 15684 사다리조작 ] 문제 풀이(Java) - 삼성 SW역량테스트 기출 (0) | 2020.04.29 |