n개의 값 중에서 r 개의 숫자를 순서를 고려해 나열한 경우의 수
[1, 2, 3] 이라는 3 개의 배열에서 2 개의 숫자를 뽑는 경우는 6개임
[1, 2][1, 3]
[2, 1][2, 3]
[3, 1][3, 2]
구현에는 2가지 방법이 있음
시간 복잡도: O(n!)

순열 및 조합을 생성할 때 재귀적으로 구현하지 않고, 각 인덱스 값을 비교하여 모든 경우의 인덱스 값을 뽑아내는 방법
과정
배열을 오름차순의 순열로 만들어놓고 시작해 아래 과정을 반복
ex) 1, 2, 3, 4, 5, 6, 7, ... , i
💡 관련 문제:백준 10972 다음 수열
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static int[] arr;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
int N = Integer.parseInt(br.readLine());
arr = new int[N];
st = new StringTokenizer(br.readLine());
for (int i = 0; i < N; i++) {
arr[i] = Integer.parseInt(st.nextToken());
}
if (check()) {
for (int i = 0; i < N; i++)
System.out.print(arr[i] + " ");
} else
System.out.println(-1);
}
static boolean check() {
// 1. 가장 뒤 쪽(i)부터 i-1 < i이 성립될 때 까지 i-- 하며 탐색해 교환할 위치(i-1) 찾기
int i = arr.length - 1;
while (i > 0 && arr[i-1] > arr[i])
i--;
if (i <= 0)
return false;
// 2. 가장 뒤 쪽(j)부터 i-1 < j이 성립될 때 까지 j-- 하며 탐색해 i-1와 교환할 j 찾기
int j = arr.length - 1;
while (arr[i-1] > arr[j])
j--;
// 3. i-1과 j의 값 교환
swap(i-1, j);
// 4. 가장 큰 값인 i부터 가장 마지막 값인 j까지 다시 오름차순 정렬
j = arr.length-1;
while (i < j) {
swap(i, j);
i++;
j--;
}
return true;
}
static void swap(int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}

👉 관련 문제: 백준 10819 차이를 최대로
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static int[] arr, res;
static boolean[] visited;
static int sum, result;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
int N = Integer.parseInt(br.readLine());
arr = new int[N]; // 입력받을 배열
res = new int[N]; // 탐색하며 새로 생성할 배열
visited = new boolean[N];
st = new StringTokenizer(br.readLine());
for (int i = 0; i < N; i++) {
arr[i] = Integer.parseInt(st.nextToken());
}
dfs(0);
System.out.println(result);
}
static void dfs(int depth) {
if (depth == arr.length) {
sum = 0;
for (int i = 0; i < res.length; i++) {
System.out.print(res[i] + " ");
}
System.out.println();
return;
}
for (int i = 0; i < arr.length; i++) {
if (!visited[i]) {
visited[i] = true;
res[depth] = arr[i];
dfs(depth+1);
visited[i] = false;
}
}
}
}