Taaewoo
Data Engineering Blog
Taaewoo
전체 방문자
오늘
어제
  • 분류 전체보기 (67)
    • Computer Science (16)
      • Algorithm (6)
      • OS (1)
      • Java (2)
      • C++ (6)
      • Python (1)
    • Hadoop Ecosystem (27)
      • Hadoop (6)
      • Spark (5)
      • NiFi (6)
      • Hive (9)
      • Kafka (1)
    • BigData Engineering (14)
      • Jupyter (1)
      • Docker (3)
      • CDH (3)
      • Riot Data Pipeline (7)
    • Back-end 개발 (0)
      • Spring (0)
    • Algorithm 문제 풀이 (9)
      • 백준 (5)
      • LeetCode (4)
    • Conference (1)
      • LINE DEVELOPER DAY 2021 (1)
      • if(kakao) 2021 (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • sort
  • kafka
  • hadoop
  • 프로그래밍
  • Coding
  • java
  • 정렬
  • spark
  • NiFi
  • 코딩
  • metastore
  • 알고리즘
  • 빅데이터
  • CS
  • BigData
  • hdfs
  • C++
  • docker
  • algorithm
  • Hive

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Taaewoo

Data Engineering Blog

[Algorithm][투 포인터] 백준 1806 - 부분합
Algorithm 문제 풀이/백준

[Algorithm][투 포인터] 백준 1806 - 부분합

2021. 10. 6. 02:32

알고리즘 분류

 투 포인터

 

시간 복잡도

 \( O(N) \)

 

문제 링크

https://www.acmicpc.net/problem/1806


 이번 문제의 알고리즘 종류는 투 포인터입니다. 주어진 배열에서 조건을 만족하는 연속된 수들 중 가장 짧은 길이를 알아야 합니다. 문제의 제목은 부분합이지만 실제로 이 문제를 푸는데 지난번에 다뤘던 부분합 알고리즘이 사용되진 않습니다. 왜냐하면 부분합 알고리즘은 각 지점마다 누적된 합을 구해놓고 특정 구간의 합만 구하면 되지만 이번 문제는 조건을 만족하는 모든 구간을 알아봐야하기 때문입니다.

 

 투 포인터의 핵심은 "배열이 끝날 때까지 크면 줄이고 작으면 늘린다"입니다. 투 포인터는 배열을 처음부터 탐색하게 되는데 특정 구간의 시작점을 나타내는 S와 끝 지점을 나타내는 E가 있습니다. S부터 E까지의 합을 문제의 조건과 비교하여 크면 부분합을 줄이기 위해 S를 +1 합니다. 반대로 조건보다 작다면 부분합을 늘리기 위해 E를 +1 합니다. 하지만 주의할 점은 E를 +1하기 전에 배열의 끝까지 탐색을 했는지 체크를 먼저 해야합니다.

 

 문제에 따라 투 포인터 알고리즘이 다양한 형태로 사용될 수 있지만 이번 문제는 가장 기본적인 문제입니다. 배열을 처음부터 위에서 말한 방식대로 검사해서 최소 길이만 구하면 됩니다. 부분합 조건을 15라고 가정했을 때 아래의 예시를 통해 흐름을 확인하겠습니다.

 

 시간은 부분합을 최대로 길게 늘인 후 다시 최소로 줄이는 경우 또는 늘리기와 줄이기를 번갈아가며 진행하는 경우가 가장 최악의 경우입니다. 하지만 이 경우에도 2N만큼의 탐색 시간이므로 시간 복잡도는  \( O(N) \)입니다.

 

Java

import java.util.*;

public class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int t = sc.nextInt();
        int[] arr = new int[100000];

        for(int i=0; i<n; i++)
            arr[i] = sc.nextInt();

        int s=0, e=0, sum=0, ans=987654321;
        while(true){
            if(sum >= t){
                ans = Math.min(ans,e-s);
                sum -= arr[s++];
            }
            else if(e >= n) break;
            else sum += arr[e++];
        }

        System.out.println(ans==987654321 ? 0 : ans);
    }
}

 

C++

#include <iostream>
using namespace std;

int N,S;
int arr[100000];

int main() {
    cin >> N >> S;
    for(int i=0; i<n; i++) cin >> arr[i];
    
    int s=0,e=0,sum=0,ans=987654321;
    while(1){
        if(sum >= S){
            ans = min(ans,e-s);
            sum -= arr[s++];
        }
        else if(e == N) break;
        else sum += arr[e++];
    }
    
    cout << (ans==987654321 ? 0 : ans);
}
저작자표시 비영리 (새창열림)

'Algorithm 문제 풀이 > 백준' 카테고리의 다른 글

[Algorithm][Union Find] 백준 1717 - 집합의 표현  (0) 2021.10.08
[Algorithm][BFS] 백준 13549 - 숨바꼭질 3  (0) 2021.10.04
[Algorithm][부분 합] 백준 11659 - 구간 합 구하기 4  (0) 2021.09.29
[Algorithm][위상 정렬] 백준 2252 - 줄 세우기  (0) 2021.09.28
    'Algorithm 문제 풀이/백준' 카테고리의 다른 글
    • [Algorithm][Union Find] 백준 1717 - 집합의 표현
    • [Algorithm][BFS] 백준 13549 - 숨바꼭질 3
    • [Algorithm][부분 합] 백준 11659 - 구간 합 구하기 4
    • [Algorithm][위상 정렬] 백준 2252 - 줄 세우기
    Taaewoo
    Taaewoo

    티스토리툴바