- Today
- Total
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 29 |
30 | 31 |
- 비트마스킹
- kotiln
- #충무로맛집#골목식당#스테이크#
- 싸피
- 삼성청년sw아카데미
- Kotlin
- bitmasking
- 아키텍처패턴
- nullalble
- tomtoc
- 삼성역량테스트
- 투포인터
- 알고리즘
- lateinit
- 자바
- 삼성파우치
- 백준
- 안드로이드#코틀린#디자인패턴#싱글턴패턴#개발#앱개발
- MVVM
- ssafy서울
- 코틀린
- DataBinding
- 탐탁삼성파우치
- 탐탁노트북파우치
- Java
- Android
- 코딩테스트
- 안드로이드
- Higher-Order
- 등산로조성
공상하는 개발자
[알고리즘/JAVA] 투포인터 알고리즘 본문
투포인터 알고리즘을 소개하고자 한다.
코딩 테스트에 많이 나오는 유형이라서 알면 매우 좋을 것 같다.
그럼 고고~
투포인터 알고리즘
투포인터는 선형 시간으로 알고리즘을 풀 수 있게 만들어주는 마법의 알고리즘이다. 하지만 매우 간단해서 구현도 할 만하다. 알기만 하면 그냥 써먹으면 된다!
투포인터는 연속적인 값들을 이용해 푸는 문제에 적합하다.
2003번: 수들의 합 2
첫째 줄에 N(1≤N≤10,000), M(1≤M≤300,000,000)이 주어진다. 다음 줄에는 A[1], A[2], …, A[N]이 공백으로 분리되어 주어진다. 각각의 A[x]는 30,000을 넘지 않는 자연수이다.
www.acmicpc.net
일단 백준 2003 문제를 읽고 오자. 간단하니까 금방 읽을 수 있다.
이 문제는 정수로 된 배열이 주어지고, 연속된 구간에서 합이 일정 값과 같다면 카운트를 올려서 정답을 출력해야 한다. 이 문제에서 선형 시간인 O(n)으로 풀 수 있는 투포인터 알고리즘을 적용해보자.
풀이 방법
- 배열의 하나의 인덱스를 가리키는 Start 점과 End 점 두 개를 만들자.(start는 시작 지점, End는 끝점을 가리킨다.)
- 처음 start와 end는 0으로 초기화해준다.
- start 점부터 end점까지의 합을 구해서 sum에 저장해준다. (처음 sum은 0에서 0까지니까 배열의 0번째 인덱스 값이 저장된다.)
- 배열을 도는데 세 가지 조건으로 돈다.
- sum == 찾고자 하는 값 --> 값을 만족하는 구간을 찾았으니 cnt(카운트 개수)를 하나 늘려주고, sum의 값에서 start인덱스의 값을 빼주고 1을 늘려준다. 그리고 end값을 1을 더한 후 그 인덱스의 값을 sum에 더해준다. (말이 좀 복잡한데 직접 문제를 생각해보면 뭔 말인지 이해할 것이다.)
- sum < 찾고자 하는 값 --> sum이 더 작으니까 값을 늘려주어야 한다. start 값은 그대로 두고, end 값을 1 늘려주고 그 end 인덱스의 값을 sum에 더해준다.
- sum > 찾고자 하는 값 --> sum이 더 크니까 값을 줄여주어야 한다. end 값은 그대로 두고, start 인덱스 값을 sum에서 빼주고 start값을 1 늘려서 갱신해준다.
- 루프를 탈출하는 경우는 start 값이나 end 값이 배열의 인덱스를 초과하면 예외처리를 통해 탈출한다.(이 방법은 권장하지 않으니 다른 방법을 생각해보기 바란다.)
풀이 코드
package Baekjoon2;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Baekjoon_2003_수들의합2 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer token = new StringTokenizer(br.readLine());
int N = Integer.parseInt(token.nextToken());
int M = Integer.parseInt(token.nextToken());
token = new StringTokenizer(br.readLine());
int[] arr = new int[N];
for (int i = 0; i < N; i++) {
arr[i] = Integer.parseInt(token.nextToken());
}
int cnt = 0;
// 1.배열의 하나의 인덱스를 가리키는 Start 점과 End 점 두개를 만들자.(start는 시작지점, End는 끝점을 가리킨다.)
// 2.처음 start와 end는 0으로 초기화해준다.
int start = 0;
int end = 0;
int sum = 0;
// 3. start 점부터 end점까지의 합을 구해서 sum 에 저장해준다.
for (int i = start; i <= end; i++) {
sum += arr[i];
}
for (int i = 0;; i++)
try {
if (sum == M) {
cnt++;
sum = sum + arr[++end] - arr[start++];
} else if (sum < M) {
sum += arr[++end];
} else {
sum -= arr[start];
start++;
}
} catch (Exception e) {
break;
}
System.out.println(cnt);
}
}
투포인터 그림 설명
배열 {1,2,3,2,5}에서 합이 5인 부분 연속 수열을 찾는 문제를 그림으로 설명하겠다.
결론
투포인터는 코딩 테스트에 정말 자주 등장하는 알고리즘이다. 개념도 그렇게 어렵지 않으니 한번 익혀놓으면 좋을 것 같다!!
다들 열심히 해서 높은 곳에서 만났으면 좋겠다. 그럼 안녕...
'개발 > 알고리즘' 카테고리의 다른 글
[동적 프로그래밍/JAVA] 메모이제이션 파헤치기 (0) | 2020.10.18 |
---|---|
[알고리즘] 비트마스크(BitMask) 스킬 숙련하기(feat. 백준 1194 달이 차오른다, 가자.) (0) | 2020.05.17 |
[알고리즘/JAVA] SWEA 1949 등산로 조성 (BFS,DFS) (0) | 2020.05.03 |
[알고리즘/자바] 다익스트라 알고리즘 (Dijkstra Algorithm) (1) | 2020.04.26 |
[코딩테스트 후기] 2020 라인 코딩테스트 후기(문제 해설X,찐 후기) (0) | 2020.04.06 |