투포인터 알고리즘 (백준 2018, 1940)

Kim Dong Kyun·2023년 5월 30일
1

문제 링크

문제를 간략히 설명하면 위와 같다

"연속된" 자연수로 주어진 자연수 15를 만들기 위한 방법의 개수를 리턴하라

15를 만드는 연속된 자연수는

{1,2,3,4,5}, {4,5,6}, {7,8}, {15} 의 네가지다

주어진 N의 크기가 매~우 크고 (1000만), 따라서 O(nLogN)보다 작은 O(N)으로풀어야 함.


문제 풀이

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();

        int start = 1; // 시작 값
        int end = 1; // 끝 값
        int sum = 0; // 현재까지의 합
        int count = 0; // 경우의 수

        while (start <= N) {
            if (sum < N) {
                sum += end; // 현재까지의 합에 end 값을 더함
                end++; // end 값을 증가시킴
            } else if (sum == N) {
                count++; // 경우의 수를 증가시킴
                sum -= start; // 현재까지의 합에서 start 값을 빼고
                start++; // start 값을 증가시킴
            } else { // sum > N
                sum -= start; // 현재까지의 합에서 start 값을 빼고
                start++; // start 값을 증가시킴
            }
        }

        System.out.println(count);
    }
}
  • start ~ end까지의 sum을 저장해서, 타겟 N과 비교한다
  • sum < N 일 경우, 스타트에서 엔드까지의 총합이 N보다 작으므로 섬에다가 엔드를 더하고, 엔드를 하나 올려준다
  • sum > N 일 경우 스타트~엔드 총합이 N을 오버했으므로 섬에서 스타트를 빼주고, 스타트를 증가시킨다
  • 마지막으로 같을경우 카운트(정답)을 하나 올리고, 섬에서 스타트를 뺀 후 다시 스타트를 올려준다.

문제 링크

마찬가지로 간단한 투포인터 알고리즘. 위의 문제와 다른 것은 "2개"만 더하라는 것.

    public static class BOJ1940 {

        public static void main(String[] args) throws IOException {
            BufferedReader br = 
            new BufferedReader(new InputStreamReader(System.in));
            BufferedWriter bw = 
            new BufferedWriter(new OutputStreamWriter(System.out));

            int N = Integer.parseInt(br.readLine());
            int M = Integer.parseInt(br.readLine());
            int[] arr = new int[N];

            StringTokenizer st = new StringTokenizer(br.readLine());
            for(int i=0; i<N; i++) {
                arr[i] = Integer.parseInt(st.nextToken());
            }

            Arrays.sort(arr);

            int i=0, j=arr.length-1;
            int cnt = 0;

            while(i < j) {
                if(arr[i] + arr[j] == M) {
                    i++;
                    j--;
                    cnt++;
                }
                else {
                    if(arr[i] + arr[j] > M) {
                        j--;
                    }
                    else {
                        i++;
                    }
                }
            }

            bw.write(String.valueOf(cnt));

            br.close();
            bw.close();
        }
    }
  • 투포인터 사용하기 위해 먼저 Arrays.sort()
  • 맨 앞과 끝을 서로 더해가면서 찾는다(2개씩만)
  • i + j == 일경우 양쪽에서 하나 좁힌다
  • i + j > M 일경우 오른쪽에서 하나 내려온다
  • i + j < M 일경우 왼쪽에서 하나 올라간다

생각보다 까다롭다. 더 풀어보자

0개의 댓글