Next Permutation ๋‹ค์Œ ์ˆœ์—ด

ํ˜„ ์ˆœ์—ด์—์„œ ์‚ฌ์ „์ˆœ์œผ๋กœ ๋‹ค์Œ์— ์˜ฌ ์ˆœ์—ด์„ ์ฐพ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜

์•Œ๊ณ ๋ฆฌ์ฆ˜

  1. ๋ฐฐ์—ด์„ ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌ
  2. ๋ฐฐ์—ด์˜ ๋งจ ๋’ค ์›์†Œ๋ถ€ํ„ฐ ํƒ์ƒ‰ํ•˜์—ฌ ์ตœ์ดˆ๋กœ ๊ฐ’์ด ์ž‘์•„์ง€๋Š” ์ˆœ๊ฐ„์˜ ์ธ๋ฑ์Šค ์ฐพ๊ธฐ(i : ๊ผญ๋Œ€๊ธฐ, i ์ดํ›„๋กœ ์ตœ์ดˆ๋กœ ๊ฐ’์ด ์ž‘์•„์ง€๋Š” i-1 ์ธ๋ฑ์Šค๋ฅผ ํƒ€๊ฒŸ์œผ๋กœ ์„ ์ •)
  3. ๋ฐฐ์—ด์˜ ๋งจ ๋’ค ์›์†Œ๋ถ€ํ„ฐ ํƒ์ƒ‰ํ•˜์—ฌ ํƒ€๊ฒŸ ์›์†Œ์ธ i-1 ์ดํ›„ ์›์†Œ๋“ค ์ค‘, ํƒ€๊ฒŸ ์›์†Œ๋ณด๋‹ค ํฌ๋˜ ๊ฐ€์žฅ ์ž‘์€ ์›์†Œ(j)๋ฅผ ์ฐพ๊ธฐ
  4. i-1 ์ธ๋ฑ์Šค ์›์†Œ์™€ j ์ธ๋ฑ์Šค ์›์†Œ๋ฅผ ๊ตํ™˜
  5. ํƒ€๊ฒŸ ์›์†Œ ์ดํ›„ ๊ผญ๋Œ€๊ธฐ์ธ i ์ธ๋ฑ์Šค๋ถ€ํ„ฐ ๋งˆ์ง€๋ง‰ ์ธ๋ฑ์Šค๊นŒ์ง€์˜ ์›์†Œ๋ฅผ ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌ

Next Permutation์„ ์ด์šฉํ•œ ์ˆœ์—ด ๊ตฌํ˜„

Java
public class NextPermutationTest {
    
    public static void main(String[] args) {
        int[] arr = {10, 5, 3, 7};

        Arrays.sort(arr);     // ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌ(์‚ฌ์ „์ˆœ์œผ๋กœ ๊ฐ€์žฅ ์ž‘์€ ์ˆœ์—ด)

        // ์œ„์—์„œ ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•œ ์ƒํƒœ๊ฐ€ ์ˆœ์—ด์˜ ํ•œ ๊ฒฝ์šฐ์˜ ์ˆ˜์ด๋ฏ€๋กœ ์ˆœ์—ด์„ ์ด์šฉํ•˜๋Š” ์ž‘์—… ์ˆ˜ํ–‰ ํ›„ ์ˆœ์—ด ๋งŒ๋“ค๊ธฐ ์ง„ํ–‰
        do {
            System.out.println(Arrays.toString(arr));
        } while (nextPerm(arr));

    }

    // next permutation ๋ฉ”์„œ๋“œ
    private static boolean nextPerm(int[] arr) {
        // ๊ผญ๋Œ€๊ธฐ ์ด์ „์˜ ์›์†Œ ๊ตฌํ•˜๊ธฐ
        int biggest = arr.length-1;
        while (biggest>0 && arr[biggest-1] >= arr[biggest]) biggest--;

        // ๊ผญ๋Œ€๊ธฐ ์›์†Œ๊ฐ€ ๋ฐฐ์—ด์˜ ์ฒซ๋ฒˆ์งธ๋ผ๋ฉด ์ด๋ฏธ ๋ชจ๋‘ ์ •๋ ฌ๋œ ์ˆœ์—ด์ด๋ฏ€๋กœ false ๋ฐ˜ํ™˜
        if (biggest == 0) return false;

        // ๊ผญ๋Œ€๊ธฐ ์ด์ „ ์›์†Œ์™€ ๊ตํ™˜ํ•  ์›์†Œ ์ฐพ๊ธฐ. ๊ผญ๋Œ€๊ธฐ ์ดํ›„ ์›์†Œ๋“ค ์ค‘ ๊ผญ๋Œ€๊ธฐ ์ด์ „ ์›์†Œ๋ณด๋‹ค ํฌ๋˜, ๊ฐ€์žฅ ์ž‘์€ ์›์†Œ ์ฐพ๊ธฐ
        int swapTarget = arr.length-1;
        while (arr[biggest-1] >= arr[swapTarget]) swapTarget--;

        // ์œ„์—์„œ ์ฐพ์€ ๋‘ ์›์†Œ ๊ตํ™˜
        swap(arr, biggest-1, swapTarget);

        // ๊ผญ๋Œ€๊ธฐ๋ถ€ํ„ฐ ๋งˆ์ง€๋ง‰ ์ธ๋ฑ์Šค๊นŒ์ง€์˜ ์›์†Œ๋Š” ๋‹ค์‹œ ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌ
        int smallest = arr.length-1;
        while (smallest > biggest) {
            swap(arr, biggest++, smallest--);
        }

        return true;
    }

    // ์›์†Œ 2๊ฐœ ๊ตํ™˜ ๋ฉ”์„œ๋“œ
    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

์‘์šฉ - Next Permutation์„ ์ด์šฉํ•œ ์กฐํ•ฉ ๊ตฌํ˜„

Java
public class NextPermCombiTest {
    
    public static void main(String[] args) {
        int[] arr = {10, 5, 3, 7};
        int N = arr.length, R = 3;     // ๋ฐฐ์—ด ์›์†Œ ์ค‘ R๊ฐœ ๋งŒํผ ๋ฝ‘์Œ
        int[] combi = new int[N];      // ์„ ํƒํ•  ์›์†Œ ์ฒดํฌ ๋ฐฐ์—ด

        for (int i=N-1; i>=N-R; i--) combi[i] = 1;     // ์„ ํƒํ•  ์›์†Œ ์กฐํ•ฉ(N๊ฐœ ์ค‘ R๊ฐœ๋งŒ ์ฒดํฌ)์„ ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ดˆ๊ธฐํ™”

        // ์œ„์—์„œ ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•œ ์ƒํƒœ๊ฐ€ ์กฐํ•ฉ์˜ ํ•œ ๊ฒฝ์šฐ์˜ ์ˆ˜์ด๋ฏ€๋กœ ์กฐํ•ฉ์„ ์ด์šฉํ•˜๋Š” ์ž‘์—… ์ˆ˜ํ–‰ ํ›„ ์กฐํ•ฉ ๋งŒ๋“ค๊ธฐ ์ง„ํ–‰
        do {
            // ์„ ํƒ๋œ ๊ฒฝ์šฐ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์กฐํ•ฉ ๊ตฌ์„ฑ
            for (int i=0; i<N; i++){
                if (combi[i] == 1) System.out.print(arr[i] + " ");
            }
            System.out.println();
        } while (nextPerm(combi));

    }

    // ์ˆœ์—ด ์ฝ”๋“œ์ธ ์•„๋ž˜ ์ฝ”๋“œ๋Š” ์ˆ˜์ •ํ•˜์ง€ ์•Š์•„๋„ ์กฐํ•ฉ ๊ตฌ์„ฑ ๊ฐ€๋Šฅ!
    // next permutation ๋ฉ”์„œ๋“œ
    private static boolean nextPerm(int[] arr) {
        // ๊ผญ๋Œ€๊ธฐ ์ด์ „์˜ ์›์†Œ ๊ตฌํ•˜๊ธฐ
        int biggest = arr.length-1;
        while (biggest>0 && arr[biggest-1] >= arr[biggest]) biggest--;

        // ๊ผญ๋Œ€๊ธฐ ์›์†Œ๊ฐ€ ๋ฐฐ์—ด์˜ ์ฒซ๋ฒˆ์งธ๋ผ๋ฉด ์ด๋ฏธ ๋ชจ๋‘ ์ •๋ ฌ๋œ ์ˆœ์—ด์ด๋ฏ€๋กœ false ๋ฐ˜ํ™˜
        if (biggest == 0) return false;

        // ๊ผญ๋Œ€๊ธฐ ์ด์ „ ์›์†Œ์™€ ๊ตํ™˜ํ•  ์›์†Œ ์ฐพ๊ธฐ. ๊ผญ๋Œ€๊ธฐ ์ดํ›„ ์›์†Œ๋“ค ์ค‘ ๊ผญ๋Œ€๊ธฐ ์ด์ „ ์›์†Œ๋ณด๋‹ค ํฌ๋˜, ๊ฐ€์žฅ ์ž‘์€ ์›์†Œ ์ฐพ๊ธฐ
        int swapTarget = arr.length-1;
        while (arr[biggest-1] >= arr[swapTarget]) swapTarget--;

        // ์œ„์—์„œ ์ฐพ์€ ๋‘ ์›์†Œ ๊ตํ™˜
        swap(arr, biggest-1, swapTarget);

        // ๊ผญ๋Œ€๊ธฐ๋ถ€ํ„ฐ ๋งˆ์ง€๋ง‰ ์ธ๋ฑ์Šค๊นŒ์ง€์˜ ์›์†Œ๋Š” ๋‹ค์‹œ ์˜ค๋ฆ„์ฐจ์ˆœ ์ •๋ ฌ
        int smallest = arr.length-1;
        while (smallest > biggest) {
            swap(arr, biggest++, smallest--);
        }

        return true;
    }

    // ์›์†Œ 2๊ฐœ ๊ตํ™˜ ๋ฉ”์„œ๋“œ
    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}