博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
46. 47. Permutations and Permutations II 都适用(Java,字典序 + 非字典序排列)
阅读量:7112 次
发布时间:2019-06-28

本文共 3190 字,大约阅读时间需要 10 分钟。

解析:

一:非字典序(回溯法)

           1)将第一个元素依次与所有元素进行交换;

           2)交换后,可看作两部分:第一个元素及其后面的元素;

           3)后面的元素又可以看作一个待排列的数组,递归,当剩余的部分只剩一个元素时,得到一个排列;

           4)将第1步中交换的元素还原,再与下一个位元素交换。

           重复以上4步骤,直到交换到最后一个元素。(剑指offer中也有例题讲解)

           排除重复:在for循环中,从start开始,每次与当前的i位置元素交换,每次交换前,

           需要判断start到i之间(不包括i)是否具有同i位置相同的元素,若存在,则跳过该轮循环,从而避免重复排列的产生。

二:字典序,该方法本身具有去除重复的作用。

           根据当前序列,生成下一个序列,交换 + 逆序。当得到一个排列中所有元素已经逆序时,说明这是最后一个排列了。

代码:

一:非字典序(回溯法)

public static void main(String[] args) {        // TODO Auto-generated method stub        //定义数组        int[] array = {1,1,3};        List
> list = new ArrayList
>(); int start = 0; //去重 list = getAllPermutations(array, new ArrayList
>(), start); System.out.println(list); } /** * 方法一:非字典序 * 判断当前要交换的字符在前面是否已经出现过,若已经出现过,则不交换 * * @param array * @return */ public static List
> getAllPermutations(int[] array,List
> list,int start){ if(start == array.length){ //遍历到最后一个 List
item = new ArrayList
(array.length); for(int i = 0,len = array.length; i < len; ++i) item.add(array[i]); list.add(item); } for(int i = start,len = array.length; i < len; ++i){ boolean flag = false; for(int j = start; j < i; ++j) //i是待交换元素,start到i之间(不包括i),若出现过同i相同的元素,则不再交换 if(array[j] == array[i])//若存在重复数字,则不交换 flag = true; if(!flag){ swap(array,i,start); //递归在循环里 getAllPermutations(array,list,start + 1); //回溯 swap(array,i,start); } } return list; } /** * 交换元素 * @param array * @param i * @param j */ public static void swap(int[] array,int i ,int j){ //交换 int tmp = array[i]; array[i] = array[j]; array[j] = tmp; }

二、字典序

/**     * 字典序     * @return     */    public static List
> permutations(int[] array,List
> list){ //将原数组加入结果集 List
item = new ArrayList
(); for(int j = 0,l = array.length; j < l; ++j) item.add(array[j]); list.add(item); while(!isLastOne(array)){ list.add(nextPermutation(array)); } return list; } /** * 判断数组元素是否逆序,若已经逆序,说明已经是全部排列的最后一个 * @param array * @return */ public static boolean isLastOne(int[] array){ for(int i = 0; i < array.length - 1; ++i){ if(array[i] < array[i + 1]) return false; } return true; } /** * 获取下一个字典序的排列 * @return */ public static List
nextPermutation(int[] nums){ if(nums == null) return null; if(nums.length == 0) return new ArrayList
(); //长度为1的数组 if (nums.length == 1) { return new ArrayList
(nums[0]); } //存储结果 List
result = new ArrayList
(); //从后向前找到第一个不满足逆序的元素 int i = nums.length - 2; for(; i >= 0 && nums[i] >= nums[i + 1]; --i); //注意,这里有=,可以排除含有重复元素的情况 //从i+1位置开始,向后查找比nums[i]大的最小元素 if(i >= 0){ int j = i + 1; for(; j < nums.length && nums[j] > nums[i]; ++j); swap(nums,i,j - 1); //交换,注意是同 j - 1交换 } //将i之后的元素逆置(这里包含一种特殊情况,若该排列已经是字典序中的最大了,则下一个序列应该是最小字典序,因此,直接在这里逆置即可) int k = nums.length - 1; i++; for(; i < k; i++, k--) swap(nums, i, k); for(int l = 0,len = nums.length; l < len; ++l) result.add(nums[l]); return result; } /** * 交换元素 * @param array * @param i * @param j */ public static void swap(int[] array,int i ,int j){ //交换 int tmp = array[i]; array[i] = array[j]; array[j] = tmp; }

 

转载于:https://www.cnblogs.com/mydesky2012/p/5767719.html

你可能感兴趣的文章
pip 安装flask
查看>>
7.springboot --dubbo 了解
查看>>
HTML 教程
查看>>
一道受用终生的面试题,谁能给出最好的答案
查看>>
java 报表的计算公式
查看>>
EOF是什么?
查看>>
Java8 默认方法简介
查看>>
Ubuntu下使用LAMP
查看>>
【转】技术普及帖:你刚才在淘宝上买了一件东西
查看>>
浅谈android截屏问题
查看>>
ElasticSearch 搜索总结
查看>>
分布式文件系统HDFS简要介绍
查看>>
LocalDB 惹得祸
查看>>
工作量单位-人月、人日、人时 详解
查看>>
向上、下转型理解★★★
查看>>
Redis面试题
查看>>
C++堆-栈-自由存储区-全局静态存储区和常量存储区-托福答案考前qq5471204-SAT答案...
查看>>
淘宝SOA框架dubbo学习(1)--first demo
查看>>
MongoDB编程系列(20)——数据库、集合、文档、键值查询(新老API)
查看>>
不要在foreach循环里进行元素的remove/add操作
查看>>