다음 순열 구하기(Next Permutation)

2022. 8. 16. 00:51· Algorithm/알고리즘 개념
목차
  1. 개요
  2. 장점
  3. 단점
  4. 구현
  5. 소스코드
  6. 참조 사이트

목차

     

     

     

    개요

    순열 및 조합을 생성할 때 재귀적으로 구현하지 않고 각 인덱스 값을 비교하여 모든 경우의 인덱스 값을 뽑아내는 방법입니다. 

    현 순열에서 사전 순(오름차순)으로 다음 순열을 생성합니다. 즉 배열을 가장 작은 값으로 정렬한 뒤, 한 자리씩 swap 하면 서 출력합니다.

     

    예시) 1 2 3

    1 3 2 
    2 1 3 
    2 3 1
    3 1 2
    3 2 1 (가장 큰 값)

     

     

     

    장점

    • 재귀로 짜여진 순열과 달리 시간 복잡도가 낮습니다. (재귀적 호출이 없고 인덱스의 값만 교체해주므로)
    • 순열과 조합을 함께 사용할 수 있습니다.

     

    단점

    • 원래의 배열을 재배열하여 순열을 만드므로 nPr 과 같이 특정 개수의 순열을 만들 수 없습니다. 

     

     

    구현

    소스 배열을 오름차순으로 정렬합니다. (1, 2, 3...)

    (모든 탐색은 오른쪽에서 왼쪽으로 진행됩니다.)

     

    오른쪽에서 왼쪽으로 탐색을 하면서 숫자가 작아지는 부분을 체크합니다. (꼭대기값 찾기, 인덱스 : i)

    1 2 4 3

    -> 4에서 2로 가는 부분이 숫자가 작아지는 부분입니다.

    -> 2의 인덱스인 1을 i-1, 4의 인덱스 3을 i로 저장합니다.

    -> 꼭대기값은 i가 됩니다. 만약 i가 0이면 마지막 순열까지 탐색한 것이므로 종료합니다.

     

    교환위치를 알기 위해 맨 오른쪽부터 탐색합니다. (인덱스 : j)

    j 는 i - 1 보다 큰 값입니다. 탐색을 했다면 j와 i-1의 값을 교체(swap) 합니다.  

    1 2 4 3 

    -> (i - 1) 은 2입니다. 맨 오른쪽으로 탐색했을 때 3이 2보다 크므로 j는 3이 됩니다. 

    -> (i - 1)와 j의 값을 교체합니다.

    -> 1 3 4 2

     

    교환이 완료되면 꼭대기 값부터 맨 뒤까지 오름차순으로 정렬합니다.

    이미 내림차순 정렬되어 있으므로 꼭대기값(i) 부터 맨 오른쪽 값(n-1)의 자리 수를 각각 교환 합니다. 

     

    1 3 4 2

    -> 꼭대기값(i = 2) 4부터 맨 오른쪽 값(n-1 = 3)의 자리수를 각각 교환

    -> 1 3 2 4

     

    이런 식으로 가장 큰 순열의 경우의 수가 나올때까지 반복합니다. 

     

     

     

     

     주어진 순열 

     

     

     

    꼭대기값 찾기

    arr[i-1] < arr[i] 를 만족하는 i-1를 찾습니다.

     

     

    arr[i-1]을 기준으로 arr[i-1] 보다 큰 arr[j]를 찾습니다.

    j는 맨 오른쪽부터 시작해 왼쪽으로 찾습니다.

     

     

    j 의 탐색을 마쳤으면 arr[i-1]과 arr[j]의 값을 교체(swap) 합니다.

     

     

    꼭대기값(i)부터 맨 오른쪽 값(n-1) 값을 오름차순 해줍니다. (이미 내림차순이므로 각 자릿수 별로 교체를 진행합니다.)

     

     

     

     

    소스코드

    import java.util.Arrays;
    
    public class nextpermutation {
    	
    	public static void main(String[] args) {
    		
    		int[] arr = {1,4,2,3,};
    		
    		// 오름차순 정렬 
    		Arrays.sort(arr);
    		
    		
    		do {
    			System.out.println(Arrays.toString(arr));
    		} while(np(arr));
    		
    	}
    	
    	public static boolean np(int[] arr) {
    		
    		int n = arr.length;
    		int i = n - 1;
    		
    		// 꼭대기(i) 탐색
    		while(i > 0 && arr[i-1] >= arr[i] ) i--;
    		
    		// 꼭대기가 0 이면 모든 경우를 탐색햇으므로 종료
    		if(i == 0) return false;
    		
    		// 교체할 데이터 찾기( i-1, j 교체)
    		int j = n - 1;
    		while(arr[i-1] >= arr[j]) j--;
    		swap(arr, i-1, j);
    		
    		// 꼭대기 값에서부터 맨 오른쪽까지 오름차순으로 변경
    		int k = n-1;
    		while(i < k) {
    			swap(arr, i++, k--);
    		}
    		
    		return true;
    	}
    	
    	public static void swap(int[] arr, int i, int j) {
    		int temp = arr[i];
    		arr[i] = arr[j];
    		arr[j] = temp;
    	}
    
    }

     

     

     

     

     

     

     

     

     

    참조 사이트

     

    https://velog.io/@tomato2532/NextPermutation

     

    [알고리즘] Next Permutation

    NextPermutation 현 순열에서 사전 순(오름차순)으로 다음 순열을 생성합니다. 즉 배열을 가장 작은 값으로 정렬한 뒤, 한 자리씩 swap하면서 출력합니다. 만약 숫자배열이라면 각각의 자리를 합해서

    velog.io

     

     

    https://redbinalgorithm.tistory.com/141

     

    JAVA : nextPermutation 다음순열

    nextPermutation 구현의 아이디어 nextPermuation이란 [1,2,3,4,5] ->[1,2,3,5,4] ->[1,2,4,3,5] 처럼 현재의 상태에서 다음 순열을 찾는 알고리즘이다. 물론 조합 알고리즘을 이용해서 각각의 인덱스의 조합을 이..

    redbinalgorithm.tistory.com

     

    1. 개요
    2. 장점
    3. 단점
    4. 구현
    5. 소스코드
    6. 참조 사이트
    'Algorithm/알고리즘 개념' 카테고리의 다른 글
    • 크루스칼 알고리즘(Kruskal Algorithm)
    • 유니온 파인드(Union - Find)
    • 동적 계획법(Dynamic Programming - DP)
    • 위상 정렬(Topology Sort)
    너지살
    너지살
    너지살
    너지살개발자
    너지살
    전체
    오늘
    어제
    • 분류 전체보기 (375)
      • 잡식 (2)
        • 티스토리 (2)
      • 개발 일지 (0)
        • OMS 프로젝트 (4)
        • 우테코 6기 프리코스 (1)
      • Git (2)
      • JAVA (15)
        • Java 공부 (6)
        • 자료구조 (4)
        • 도움되는 메모 (4)
      • DevOps (18)
        • AWS (6)
        • Docker (2)
        • Jenkins (1)
        • Nginx (1)
        • Kafka (6)
        • RabbitMQ (2)
      • Spring, Spring Boot (16)
        • Test Code (1)
        • AOP (2)
        • Batch (3)
        • Cache - Redis (5)
        • Cloud Config - 설정 파일 관리 (3)
        • 성능 측정 (1)
        • 예외 처리 (1)
      • BackEnd (1)
        • Spring 공부 (1)
        • Thymeleaft (0)
      • DB (17)
        • JPA (2)
        • DB 공부 (3)
        • DB 포스팅 (4)
        • DB 답장 (1)
        • MySQL (2)
        • Redis (5)
        • MongoDB (0)
      • CS (8)
        • Spring (4)
        • DataBase (3)
        • Java (1)
      • Algorithm (203)
        • 알고리즘 개념 (5)
        • 정렬 알고리즘 (11)
        • 프로그래머스 문제풀이 (18)
        • 백준 문제풀이 (165)
        • 소프티어 문제풀이 (3)
        • 알고리즘 시험 정리 (1)
      • SQL (0)
        • 문법 (1)
        • 프로그래머스 문제풀이 (52)
        • 리트코드 문제풀이 (19)
      • IT (1)
        • IT 공부 (1)
      • 정리 (10)
        • 질문 정리 (10)

    블로그 메뉴

    • 홈
    • 태그
    • 방명록

    공지사항

    인기 글

    태그

    • Algorithm
    • Spring Batch
    • Test code
    • DP
    • 부분탐색
    • Bitmast
    • 데이터베이스
    • 최소 스패닝 트리
    • 경로표현식
    • db
    • Spring Boot Redis 연결
    • 유니온파인드
    • DFS
    • 외판원 순회 문제
    • 자료구조
    • Next permutation
    • 다이나믹 프로그래밍
    • 설정
    • 다이나믹프로그래밍
    • Java
    • Spring Boot
    • 투 포인터
    • dynamiceprogramming
    • Union-Find
    • MST
    • 소프티어
    • 그래프 이론
    • cache
    • 병렬 처리
    • git
    • 그래프 탐색
    • 깊이/너비 우선탐색
    • Sorting algorithm
    • Java 정리
    • docker
    • 다음 순열 찾기
    • redis
    • 우선수위큐
    • 알고리즘
    • JPA
    • 백준
    • 최소 신장 트리
    • 질문 정리
    • 비트마스킹
    • 투포인트
    • 분리 집합
    • dynamic programing
    • two pointer
    • 크루스칼 알고리즘
    • 두 포인터

    최근 댓글

    최근 글

    hELLO · Designed By 정상우.v4.2.2
    너지살
    다음 순열 구하기(Next Permutation)
    상단으로

    티스토리툴바

    단축키

    내 블로그

    내 블로그 - 관리자 홈 전환
    Q
    Q
    새 글 쓰기
    W
    W

    블로그 게시글

    글 수정 (권한 있는 경우)
    E
    E
    댓글 영역으로 이동
    C
    C

    모든 영역

    이 페이지의 URL 복사
    S
    S
    맨 위로 이동
    T
    T
    티스토리 홈 이동
    H
    H
    단축키 안내
    Shift + /
    ⇧ + /

    * 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.