Algorithm/이둠

Next Permutation을 μ΄μš©ν•œ μ‘°ν•©

Edlin 2022. 5. 17. 21:50
  • flagλ₯Ό Next Permutation을 μ΄μš©ν•˜μ—¬ κ΅¬ν˜„ν•œ 것
  • nCr 을 κ΅¬ν•˜κ³ μž ν•  λ•Œ, 크기 n의 배열을 μƒμ„±ν•˜μ—¬ r 개의 크기만큼 0 이 μ•„λ‹Œ κ°’ μ΄ˆκΈ°ν™”

5C2 이면, 00011 둜 μ΄ˆκΈ°ν™”

  • Next Permutation μ•Œκ³ λ¦¬μ¦˜ 이용

00011을 μ‚¬μš©ν•˜μ—¬ NPλ₯Ό 돌리고 1의 μœ„μΉ˜μ— μ›μ†Œ 값이 μ„ νƒλ˜μ–΄ 쑰합을 λ§Œλ“ λ‹€.

  • Next Permutation ν•œ 번 μ΄μš©ν•  λ•Œλ§ˆλ‹€ 쑰합이 λ§Œλ“€μ–΄ μ§„λ‹€. (0이 μ•„λ‹Œ κ°’μ˜ μœ„μΉ˜κ°€ λ³€κ²½λœλ‹€)
    => r개의 크기 만큼, 즉, 0이 μ•„λ‹Œ 값이 μ„ΈνŒ…λœ 곳에 μ›μ†Œλ₯Ό μ„ νƒν•˜μ—¬ 쑰합을 λ§Œλ“  것이닀.

import java.util.Arrays;

public class Combination {
	static int N, R, nums[];

	public static void main(String[] args) {
//			nCr
		R = 3;
		N = 5;
		nums = new int[] { 1, 2, 3, 4, 5 };

		int[] set = new int[N];
		// 0보닀 큰 κ°’μœΌλ‘œ R개λ₯Ό 맨 λ’€λΆ€ν„° μ±„μš΄λ‹€.
		int cnt = 0;
		while (++cnt <= R)
			set[cnt] = 1;
		Arrays.sort(set); // μ˜€λ¦„μ°¨μˆœμœΌλ‘œ λ§Œλ“€κΈ° μœ„ν•΄μ„œ

		do {
			for(int i = 0; i < N; i++) {
				if(set[i] == 1) {
					System.out.print(nums[i]+" ");
				}
			}
			System.out.println();
			
		} while (nextPermutation(set));
	}

	// 2. κΌ­λŒ€κΈ°λ₯Ό μ°Ύμ•„μ„œ μˆœμ—΄ λ§Œλ“€κΈ°
	private static boolean nextPermutation(int[] set) {

		// 1) κΌ­λŒ€κΈ° μ°ΎκΈ°
		int i = N - 1;
		while (i > 0 && set[i - 1] >= set[i])
			--i;

		// i==0이면, λ§Œλ“€ 수 μžˆλŠ” ν˜•νƒœμ˜ μˆœμ—΄μ΄ 더이상 μ—†λ‹€λŠ” 뜻 (λ§Œλ“€ 수 μžˆλŠ” κ°€μž₯ 큰 μˆœμ—΄μ„ λ‹€ λ§Œλ“€μ—ˆλ‹€)
		if (i == 0)
			return false;

		// 2) κ΅ν™˜ μœ„μΉ˜μ— κ΅ν™˜ν•  κ°’ μ°ΎκΈ°
		int j = N - 1;
		while (set[i - 1] >= set[j])
			--j;

		// 3) κ΅ν™˜ν•  μœ„μΉ˜μ™€ κ΅ν™˜ν•  μœ„μΉ˜λ³΄λ‹€ 큰 κ°’ λ°”κΎΈκΈ°
		swap(set, i - 1, j);

		// 4) κΌ­λŒ€κΈ°λΆ€ν„° 맨 λ’€κΉŒμ§€ μ˜€λ¦„ 차순 μ •λ ¬
		int k = N - 1;
		while (i < k) {
			swap(set, i++, k--);
		}

		return true;
	}

	private static void swap(int[] set, int i, int j) {
		int temp = set[i];
		set[i] = set[j];
		set[j] = temp;
	}
}