본문 바로가기
Algorithm/Java

[BOJ] 10972 : 다음 순열 [S3]

by 코코형아 2024. 2. 13.

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

 

10972번: 다음 순열

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

www.acmicpc.net

 

 

 

[문제]

1부터 N까지의 수로 이루어진 순열이 있다. 이때, 사전순으로 다음에 오는 순열을 구하는 프로그램을 작성하시오.

사전 순으로 가장 앞서는 순열은 오름차순으로 이루어진 순열이고, 가장 마지막에 오는 순열은 내림차순으로 이루어진 순열이다.

N = 3인 경우에 사전순으로 순열을 나열하면 다음과 같다.

  • 1, 2, 3
  • 1, 3, 2
  • 2, 1, 3
  • 2, 3, 1
  • 3, 1, 2
  • 3, 2, 1

[입력]

첫째 줄에 N(1 ≤ N ≤ 10,000)이 주어진다. 둘째 줄에 순열이 주어진다.

[출력]

 

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

 

[예제 입력 1]

4
1 2 3 4

[예제 출력 1]

1 2 4 3

 

[예제 입력 2]

5
5 4 3 2 1

 

[예제 출력 2]

-1

 

 

[내 풀이]

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

/*
	문제 : [S3] 다음 순열 - 10972번
	제출 : 2024년 2월 13일
	결과 : 통과
	성능 요약 : 메모리 19672KB, 시간 400ms
	아이디어 : Next Permutation을 이용해 풀었습니다.
	
	내가 한 뻘짓 :
		1. 순열 모두 구한 후 답 구하려고함.
		2. 문자열로 입력받아서 처리하려고 함.
		3. NP 제대로 이해 못한 상태로 풀려고함.
		
*/

public class Main_10972_다음순열_남보우 {

	static int N, bindex, aindex;
	static int[] ans;
	
	public static void main(String[] args) throws Exception{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;
		N = Integer.parseInt(br.readLine());
		st = new StringTokenizer(br.readLine());
		
		ans = new int[N];
		for (int i=0; i<N; i++) {
			ans[i] = Integer.parseInt(st.nextToken());
		}
		
		boolean isSwap = false;
		for (int i=ans.length-1; i>0; i--) {
			// 오르막길 끝
			if (ans[i-1] < ans[i]) {
				isSwap = true;
				
				bindex = i-1;
				
				int maxNum = -1;
				// bindex의 위치한 값보다 큰 값중 가장 작은 값 찾음
				for (int j=ans.length-1; j>=i; j--) {
					if (ans[bindex] < ans[j]) {
						maxNum = ans[j];
						aindex = j;
						break;
					}
				}
				
				// 두 수를 스왑
				swap(bindex, aindex);
				
				
				// bindex이후 수들을 오름차순 정렬
				for (int j=0; j<(N-bindex)/2; j++) {
					swap(i + j, N-1-j);
					
				}
				break;
			}
		}
		
		if (!isSwap) System.out.println(-1);
		else {
			for (int i=0; i<N; i++) {
				System.out.print(ans[i] + " ");
			}
		}

	}
	
	// 수 교환
	static void swap(int i, int j) {
		int temp = ans[i];
		ans[i] = ans[j];
		ans[j] = temp;
	
	}

}

 

 

<회고>

Next Permutation이라는 개념 자체를 이해하는 것이 어려웠고, 이해한 개념을 코드로 구현하는 것도 쉽지 않았다.

간단하게 이해한 Next Permutation 알고리즘을 설명하면 아래와 같다.

 

Next Permutation 알고리즘

1. 뒤쪽부터 탐색하여 교환위치(i-1)을 찾는다.

  • 이때 i는 가장 높은 값(꼭대기)

2. 다시 뒤쪽부터 탐색하여 (i-1)인덱스에 위치한 값보다 큰 수중 가장 작은수를 찾는다.

3. 두 수를 교환한다.

4. 꼭대기 위치(i)부터 맨 뒤까지 다시 오름차순으로 정렬한다.

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

[BOJ] 5373 : 큐빙 [P5]  (0) 2024.03.10
[BOJ] 7576 : 토마토 [G5]  (0) 2024.03.09
[BOJ] 4179 : 불! [G4]  (0) 2024.02.12
[SWEA] 1233. 사칙연산유효성검사 [D4]  (1) 2024.02.07
[BOJ] 3055 : 탈출 [G4]  (1) 2024.02.07