Algorithm/BaekJoon

[백준] 10972: 다음 순열 (자바/Java)

하노정 2022. 11. 2. 21:10

문제

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

 

10972번: 다음 순열

첫째 줄에 입력으로 주어진 순열의 다음에 오는 순열을 출력한다. 만약, 사전순으로 마지막에 오는 순열인 경우에는 -1을 출력한다.

www.acmicpc.net

문제 풀이 

주어진 순열의 다음 순열을 구하기만 하면 된다. 

다음 순열을 구하는 방법은 다음과 같다. 

1. p[i-1] < p[i] 만족하는 가장 큰 i를 찾는다. 

2. j >= i 면서 p[j] > p[i-1] 만족하는 가장 큰 j를 찾는다.

3. p[i-1] 과 p[j] 를 swap한다.

4. p[i] 부터 순열을 뒤집는다. 오름차순으로. (i-1이 바뀌었으므로 i부터 재정렬 한다고 생각하면 됨)

 

코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class boj_10972 {
    // BufferedReader: 한 번에 모아서 전송됨
    // InputStreamReader: 입력 통로
    // System.in: 시스템 입력
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static int num;
    static int[] p;

    public static void main(String[] args) throws IOException {
        num = Integer.parseInt(br.readLine()); // 첫 줄 읽음
        p = new int[num]; // 입력한 순열 넣기 위한 배열 선언

        // 입력한 값을 공백 단위로 끊어서 st에 저장해놓음
        StringTokenizer st = new StringTokenizer(br.readLine(), " "); 
       
        for(int i = 0; i<num; i++) { // 두번째 줄 읽음
            // 공백으로 끊어놓은 st 하나씩 읽어서 입력 순열 저장
            p[i] = Integer.parseInt(st.nextToken()); 
        }

        // 다음 순열 함수 호출 (마지막 순열 값이면 -1 출력)
        if(nextPermutation()) {
        for(int i = 0; i<num; i++) {
            System.out.print(p[i] + " ");
        }} else {
            System.out.print("-1");
        }

        br.close();
    }

    public static boolean nextPermutation() {
        // 1. 뒤에서부터 p[i-1] < p[i] 인 i를 찾는다.
        int i = p.length-1; // 마지막 인덱스
        // 조건 만족 안 할 때 == p[i-1] < p[i] 인 가장 큰 i
        while(i > 0 && p[i-1] >= p[i]) i--;
     
        if(i <= 0)  return false;

        // 2. 다시 뒤에서부터 p[j] > p[i-1] 인 j를 찾음
        int j = p.length-1; // 마지막 인덱스
        // 조건 만족 안 할 때 == p[j] > p[i-1] 인 가장 큰 j
        while(j>=i && p[j] <= p[i-1]) j--;
        
        // 3. swap
        swap(i-1, j);

        // 3 5 2 4 1 -> 3 5 4 1 2
        // i는 4이고, j는 5일 때는 조건 만족 안 하므로 i가 3일 때 멈춘다. (j가 i보다 크거나 같을 때 가능)

        // 4. 오름차순 정렬
        // 다시 j에 마지막 인덱스를 대입
        // 오름차순 정렬 방법
        j = p.length-1;
        while(i < j) {
            swap(i, j);
            i++; 
            j--;
        }
        return true;
    }

    public static void swap(int idx1, int idx2) {
        int temp = p[idx1];
        p[idx1] = p[idx2];
        p[idx2] = temp;
    }
}

'Algorithm > BaekJoon' 카테고리의 다른 글

[백준] 1193: 분수찾기  (0) 2023.02.10
[백준] 2292: 벌집  (0) 2023.02.10
[백준] 2941: 크로아티아 알파벳  (0) 2023.02.08
[백준] 1157: 단어 공부  (0) 2023.02.08
[백준] 10973: 이전 순열 (자바/Java)  (0) 2022.11.02