코딩테스트

[BOJ10972/JAVA] 다음 순열

Eun 2022. 4. 23. 23:07

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

 

10972번: 다음 순열

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

www.acmicpc.net

 

문제

 

풀이

처음에는 순열 문제여서 dfs로 순열을 만든다음에 배열에 저장하고 그 배열의 다음 인덱스를 출력하려고 했으나 풀이방법이 단단히 잘못되었다. 

 

다른사람의 코드를 참고하니 애초에 값을 받은 다음에 받은 값에서 다음 순열이 무엇인지 배열의 원소를 바꾸면서 정렬해주는 식이다.

 

만약에 7 2 3 6 5 4 1 이라는 순열이 있다고 치자,

1. 맨 오른쪽 인덱스부터 시작해서 수열의 오름차순이 끝나는 지점을 찾는다. 이 말은 1부터 시작해서 하나씩 줄여나가면서 오름차순이 아닌 지점을 찾는다. 1 4 5 6 까지는 오름차순이나 3을 만나는 순간 오름차순이 끝난다.  ---> arr[i] > arr[i-1]

2. 그리고 다시 맨 오른쪽 인덱스부터 시작해서 3보다 큰 수를 찾는다. ----> arr[i-1] < arr[j]

3. 그리고 서로 자리(arr[i-1], arr[j])를 바꿔준다. 

여기까지 해주면 7 2 4 6 5 3 1 이라는 순열이 된다. 이 순열은 7 2 3 6 5 4 1 다음으로 올 수 있는 가장 큰 수이다.

4. 6(i)부터 내림차순으로 해준다. 

여기까지 하면 7 2 4 1 3 5 6 으로 바로 다음 순열이 된다.

 

이것을 어떻게 생각해내는지 ...ㅠㅠ 다들 존경스러울 따름

밑에는 이것을 구현한 코드이다.

 

코드

package Week15;

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

public class BOJ10972 {
	
	static int arr[];

	public static void main(String[] args) throws NumberFormatException, IOException {
		// TODO Auto-generated method stub
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int n = Integer.parseInt(br.readLine());
		StringTokenizer st = new StringTokenizer(br.readLine());
		arr=new int[n];
		
		for(int i=0;i<n;i++) {
			arr[i]=Integer.parseInt(st.nextToken());
		}
		
		if(nextPermutation()) {
			for(int i=0;i<n;i++) {
				System.out.print(arr[i]+" ");
			}
		}else {
			System.out.println("-1");
		}
		
	}
	
	static void swap(int i, int j) {
		int temp=arr[i];
		arr[i]=arr[j];
		arr[j]=temp;
	}
	
	
	private static boolean nextPermutation() {
	    int i = arr.length-1;
	    
	    while(i > 0 && arr[i-1] >= arr[i]) i--;
	    if(i <= 0) return false;

	    int j = arr.length-1;

	    while(arr[j] <= arr[i-1]) j--;

	    swap(i-1, j);
	    j = arr.length - 1;
	    while(i < j) {
	        swap(i, j);
	        i++;
	        j--;
	    }
	    return true;
	}



}