zoukankan      html  css  js  c++  java
  • 实现元素的全排列

        想到 前几天的一个问题,如何实现元素的全排列 并且按照升序输出。

    可以有两种方法:递归和非递归

    首先介绍非递归的方法:

    思路:

    以三个数字为例1,2,3升序的全排列为:

    1 2 3

    1 3 2

    2 1 3

    2 3 1

    3 1 2

    3 2 1

    显然每个组合  都有一个直接后继,找到一个数没有后继如 3 2 1 则停止。

    问题来了 那就是如何找到后继和没有后继的数如何判断该数是否有后继。就是对于一个数,如何找到一个比它大的,且最小的数.

    还是1 2 3为例  ,假设 此时的排列为"1 3 2" ,那么32是非递增的,而13是递增的,满足要求,然后根据要求2是比1大的最小的数,此时交换两个数的位置得到2 3 1 ,此时 把交换位置后面的数字颠倒反转即可。得到2 1 3 ,后面的排列都需要这么做,直到碰到3 2 1即可。

    代码如下

       1: public class NonRecursivePermutation {

       2:  

       3:     static int[] arr = new int[] { 1, 2, 3, 4, 5, 6 };

       4:     static int count = 1;

       5:  

       6:     // 反转区间

       7:     private static void reverse(int[] arr, int pBegin, int pEnd) {

       8:         while (pBegin < pEnd)

       9:             swap(arr, pBegin++, pEnd--);

      10:     }

      11:  

      12:     private static void swap(int[] arr, int i, int j) {

      13:         int temp;

      14:         temp = arr[i];

      15:         arr[i] = arr[j];

      16:         arr[j] = temp;

      17:     }

      18:  

      19:     private static boolean hasNext() {

      20:         for (int i = arr.length - 1; i > 0; i--) {

      21:             if (arr[i] > arr[i - 1])

      22:                 return true;

      23:         }

      24:         return false;

      25:     }

      26:  

      27:     private static void next() {

      28:         int len = arr.length;

      29:         int replace = 0; // 需替换数

      30:         int firstR = 0; // 从后向前找比替换数大的第一个数

      31:         // 找降序的相邻2数,前一个数即需替换数

      32:         for (int i = len - 1; i > 0; i--) {

      33:             if (arr[i] > arr[i - 1]) {

      34:                 replace = i - 1;

      35:                 break;

      36:             }

      37:         }

      38:         

      39:         //System.out.println("需替换数位置:" + replace);

      40:         

      41:         // 从后向前找比替换数大的第一个数

      42:         // 比如926540的后继应该是946520,而不是956240

      43:         for (int i = len - 1; i > replace; i--) {

      44:             if (arr[i] > arr[replace]) {

      45:                 firstR = i;

      46:                 break; //找到之后直接退出

      47:             }

      48:         }

      49:         

      50:         //System.out.println("替换数位置:" + firstR);

      51:         

      52:         // replace与firstR交换

      53:         swap(arr, replace, firstR);

      54:         // 替换数后的数全部反转

      55:         reverse(arr, replace + 1, len - 1);

      56:  

      57:         count++;

      58:         print();

      59:     }

      60:  

      61:     private static void print() {

      62:         for (int i = 0; i < arr.length; i++)

      63:             System.out.print(arr[i] + " ");

      64:         System.out.println();

      65:     }

      66:  

      67:     /**

      68:      * @param args

      69:      */

      70:     public static void main(String[] args) {

      71:  

      72:         while (hasNext() == true) {

      73:             next();

      74:         }

      75:         System.out.println("数组完全反转后的结果:");

      76:         reverse(arr, 0, arr.length - 1);

      77:         print();

      78:         System.out.println("全排列的数目为:" + count);

      79:  

      80:         /*********************/

      81:         System.out.println("数组是否存在后继:" + hasNext());

      82:         System.out.println("数组一次替换后的结果:");

      83:         next();

      84:     }

      85:  

     }
    

    代码的核心部分是在next和hasNext函数中。

    (下篇文章介绍递归的方法)

  • 相关阅读:
    Add Binary <leetcode>
    那些坑
    面试集锦
    随看随记
    View的事件处理流程
    android studio view.setId报错
    EditText的hint不显示
    EditText 焦点
    Android拍照的那些事
    微信支付提示签名错误
  • 原文地址:https://www.cnblogs.com/fightingxu/p/2819608.html
Copyright © 2011-2022 走看看