• 面试题1:123445排列


    题目:6个数:1,2,2,3,4,5,如何取出所有排列。

    1、

    这道题其实想法非常简单,就是从123445到544321的数字输出出来,这其中需要去掉一些无效的数字,例如6,7,8,9,0. 其实这道题还可以不断向上添加限制条件,例如要求4不能在第三个位置,3和5不能连在一起,这些条件可以和6,7,8,9,0是非法数字这个条件看做并列的条件,只要把存在这样的数字设置为无效即可。

    反思:这道题的想法非常巧妙和简单,一开始碰到这题,以为一定是用排列组合的方法来做了,我还试着用插空法来解决这个问题,后来发现实在太复杂,后来网上看到这个想法,佩服,看来还要低头多学习啊!

    代码如下:

    package job;
    
    public class Permutation2 {
    
        private static String[] forbidenNumber = new String[] { "0", "6", "7", "8", "9" };
        private static String[] mustExistNumber = new String[] { "1", "2", "2", "3", "4", "5" };
         
        private static boolean isValidNumber(String str) {
          // 检查是否有非法数字,有返回false,否则继续
          for (String number : forbidenNumber) {
           if (str.indexOf(number) >= 0) {
            return false;
           }
          }
          // 检查是否存在要的数字,如果不存在返回false,否则继续
          for (String number : mustExistNumber) {
           int temp = str.indexOf(number);
           if (temp < 0) {
            return false;
           } else if ((str.indexOf(number, temp + 1) > temp)  //就是在找到了一个number的后面再找到这个number,如果这个number不是2,那也返回false
             && str.charAt(temp) != '2') {
            return false;
           }
          }
          // 检查4在不在第三位,是返回false
          if (str.charAt(2) == '4') {
           return false;
          }
          // 检查是否存在35在一起,有返回false
          if (str.indexOf("35") >= 0 || str.indexOf("53") >= 0) {
           return false;
          }
          return true;
         }
         public static void main(String[] args) {
          // TODO code application logic here
          for (int i = 122345; i < 543221; i++) {
           if (isValidNumber(String.valueOf(i))) {
            System.out.println(i);
           }
          }
         }
    }

    http://blog.sina.com.cn/s/blog_71f4ccf90101jzdb.html

    2、

    到这里还没完,如果说我们就是想用排列组合的方法来解决怎么办?下面给出一种用递归算法解决的方法。

    先把这道题的条件降低,我们先排列1,2,3,4,5这五个数字,仔细体会递归算法的使用

    package job;
    
    public class Permutation {
    
            static int[] bits = new int[] { 1, 2, 3, 4, 5 };  
            public static void main(String[] args) {  
                sort("", bits);  
            }  
              
            private static void sort(String prefix, int[] a) {  //注意体会递归的优点,怎么想到的呢?
                if (a.length == 1) 
                System.out.println(prefix + a[0]);  
              
                for (int i = 0; i < a.length; i++) 
                    sort(prefix + a[i], copy(a, i));  
            }  
              
            private static int[] copy(int[] a,int index){  
                int[] b = new int[a.length-1];  
                System.arraycopy(a, 0, b, 0, index);  
                System.arraycopy(a, index+1, b, index, a.length-index-1);  
                return b;  
            }  
    }

    然后,我们加大条件使得和最初的条件一样:排列1,2,2,3,4,5,然后4在第三位,3和5不相连。

    基本思路: 
         把问题归结为图结构的遍历问题。图遍历思想:实际上6个数字就是六个结点,把六个结点连接成无向连通图,对于每一个结点求这个图形的遍历路径,所有结点的遍历路径就是最后对这6个数字的排列组合结果集。 
         显然这个结果集还未达到题目的要求。从以下几个方面考虑:                                                 
              3,5不能相连:实际要求这个连通图的结点3,5之间不能连通, 可在构造图结构时就满足改条件,然后再遍历图。 
              不能有重复: 考虑到有两个2,明显会存在重复结果,可以把结果集放在TreeSet中过滤重复结果 
              4不能在第三位: 仍旧在结果集中去除满足此条件的结果。

    代码如下:

    package job;
    
    import java.util.Iterator;
    import java.util.TreeSet;
    
    /**
     * 问题描述:对1,2,2,3,4,5排列,4不许在第4位,3和5不相连
     * 解决办法:基本思路: 
    2-1. 把问题归结为图结构的遍历问题。图遍历思想:实际上6个数字就是六个结点,把六个结点连接成无向连通图,对于每一个结点求这个图形的遍历路径,所有结点的遍历路径就是最后对这6个数字的排列组合结果集。 
    
    2-2. 显然这个结果集还未达到题目的要求。从以下几个方面考虑:                                                 
    
        2-2-1.   3,5不能相连:实际要求这个连通图的结点3,5之间不能连通, 可在构造图结构时就满足改条件,然后再遍历图。 
        2-2-2.   不能有重复: 考虑到有两个2,明显会存在重复结果,可以把结果集放在TreeSet中过滤重复结果 
        2-2-3.   4不能在第三位: 仍旧在结果集中去除满足此条件的结果。 
    
     * @author hanson
     *
     */
    public class Permutation3 {
    
        private String[] b = new String[]{"1", "2", "2", "3", "4", "5"};
        private int n = b.length;
        private boolean[] visited = new boolean[n];
        private int[][] a = new int[n][n];
        private String result = "";
        private TreeSet set = new TreeSet();
    
        public static void main(String[] args) {
        new Permutation3().start();
        }
    
        private void start() {
    
            // Initial the map a[][]
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    if (i == j) {
                        a[i][j] = 0;
                    } else {
                        a[i][j] = 1;
                    }
                }
            }
        
            // 3 and 5 can not be the neighbor.
            a[3][5] = 0;
            a[5][3] = 0;
        
            // Begin to depth search.
            for (int i = 0; i < n; i++) {
                this.depthFirstSearch(i);
            }
        
            // Print result treeset.
            Iterator it = set.iterator();
            while (it.hasNext()) {
                String string = (String) it.next();
                // "4" can not be the third position.
                if (string.indexOf("4") != 2) {
                    System.out.println(string);
                }
            }
        }
    
        private void depthFirstSearch(int startIndex) {
            visited[startIndex] = true;
            result = result + b[startIndex];
            if (result.length() == n) {
                // Filt the duplicate value.
                set.add(result);
        }
        for(int j = 0; j < n; j++) {
            if (a[startIndex][j] == 1 && visited[j] == false) {  //如果节点j和节点startIndex相连,且节点j没有被访问,就从j开始深度优先遍历
                depthFirstSearch(j);
            } else {
                continue;
            }
        }
    
        // restore the result value and visited value after listing a node.
            result = result.substring(0, result.length() -1);
            visited[startIndex] = false;
        }
    }

    递归的方法好难想啊!

    http://www.blogjava.net/chen45257211/articles/354718.html

  • 相关阅读:
    springboot-配置文件
    system--属性
    url--web路径
    jquery--遍历
    javascript---知识点2
    iframe
    linux--磁盘挂载
    jquery--插件
    javascript窗口宽高
    vue--知识点
  • 原文地址:https://www.cnblogs.com/hansonzhe/p/3638908.html
Copyright © 2020-2023  润新知