새소식

JAVA (개념, 알고리즘)

Two pointers, Sliding window[효율성 : O(n^2)-->O(n)]

  • -

1. 두 배열 합치기

오름차순으로 정렬이 된 두 배열이 주어지면 두 배열을 오름차순으로 합쳐 출력하는 프로그램을 작성하세요.

 

입력

첫 번째 줄에 첫 번째 배열의 크기 N(1<=N<=100)이 주어집니다.

두 번째 줄에 N개의 배열 원소가 오름차순으로 주어집니다.

세 번째 줄에 두 번째 배열의 크기 M(1<=M<=100)이 주어집니다.

네 번째 줄에 M개의 배열 원소가 오름차순으로 주어집니다.

각 리스트의 원소는 int형 변수의 크기를 넘지 않습니다.

 

출력

오름차순으로 정렬된 배열을 출력합니다.

예시 입력 1 

3
1 3 5
5
2 3 6 7 9

예시 출력 1

1 2 3 3 5 6 7 9

<코드>

import java.util.ArrayList;
import java.util.Scanner;
public class Main {
    public ArrayList<Integer> solution(int[] arr, int[] arr2)
    {
        ArrayList<Integer> answer = new ArrayList<>();
        int p1=0, p2=0;
        while (p1 < arr.length && p2 < arr2.length)
        {
            if (arr[p1] < arr2[p2])
                answer.add(arr[p1++]);
            else
                answer.add(arr2[p2++]);
        }
        while(p1<arr.length)
            answer.add(arr[p1++]);
        while(p2<arr2.length)
            answer.add(arr2[p2++]);
        
        return answer;
    }
    public static void main(String[] args)  {
        Main T = new Main();
        Scanner sc = new Scanner(System.in);

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

        int m = sc.nextInt();
        int[] arr2 = new int[m];
        for(int i=0; i<m; i++)
            arr2[i] = sc.nextInt();

        for (int x : T.solution(arr,arr2))
        {
            System.out.print(x + " ");
        }
    }
}

 

2. 연속 부분수열(two pointer)

설명

N개의 수로 이루어진 수열이 주어집니다.

이 수열에서 연속부분수열의 합이 특정숫자 M이 되는 경우가 몇 번 있는지 구하는 프로그램을 작성하세요.

만약 N=8, M=6이고 수열이 다음과 같다면

1 2 1 3 1 1 1 2

합이 6이 되는 연속부분수열은 {2, 1, 3}, {1, 3, 1, 1}, {3, 1, 1, 1}로 총 3가지입니다.

 

입력

첫째 줄에 N(1≤N≤100,000), M(1≤M≤100,000,000)이 주어진다.

수열의 원소값은 1,000을 넘지 않는 자연수이다.

 

출력

첫째 줄에 경우의 수를 출력한다.

 

예시 입력 1 

8 6
1 2 1 3 1 1 1 2

예시 출력 1

3

<코드>

import java.util.Scanner;

public class Main {
    public int solution(int n, int m, int[] a) {
        int answer=0, sum=0, lt=0;
        for (int rt=0; rt<n; rt++)
        {
            sum += a[rt];
            if (sum==m) answer++;
            while (sum >= m)
            {
                sum -= a[lt++];
                if(sum == m) answer++;
            }
        }
        return answer;
    }

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

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

        System.out.println(T.solution(n,m,a));
    }
}

lt, rt로 풀이하는 것이 참신하여 기록해본다.

 

3. 최대 길이 연속부분수열

설명

0과 1로 구성된 길이가 N인 수열이 주어집니다. 여러분은 이 수열에서 최대 k번을 0을 1로 변경할 수 있습니다. 여러분이 최대 k번의 변경을 통해 이 수열에서 1로만 구성된 최대 길이의 연속부분수열을 찾는 프로그램을 작성하세요.

만약 길이가 길이가 14인 다음과 같은 수열이 주어지고 k=2라면

1 1 0 0 1 1 0 1 1 0 1 1 0 1

여러분이 만들 수 있는 1이 연속된 연속부분수열은

이며 그 길이는 8입니다.

 

입력

첫 번째 줄에 수열의 길이인 자연수 N(5<=N<100,000)이 주어집니다.

두 번째 줄에 N길이의 0과 1로 구성된 수열이 주어집니다.

 

출력

첫 줄에 최대 길이를 출력하세요.

예시 입력 1 

14 2
1 1 0 0 1 1 0 1 1 0 1 1 0 1

예시 출력 1

8

<코드>

import java.util.Scanner;

public class Main {
    public int solution(int n, int m, int[] a) {
        int answer=0, cnt=0, lt=0;
        for(int rt=0; rt<n; rt++)
        {
            if(a[rt] == 0) cnt++;
            while(cnt > m)
            {
                if(a[lt]==0) cnt--;
                lt++;
            }
            answer = Math.max(answer, rt-lt+1);
        }
        return answer;
    }

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

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

        System.out.println(T.solution(n,m,a));
    }
}

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.