46. 47. Permutations and Permutations II 都适用(Java,字典序 + 非字典序排列)
解析:
一:非字典序(回溯法)
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<Integer>> list = new ArrayList<List<Integer>>();
int start = 0;
//去重
list = getAllPermutations(array, new ArrayList<List<Integer>>(), start);
System.out.println(list);
}
/**
* 方法一:非字典序
* 判断当前要交换的字符在前面是否已经出现过,若已经出现过,则不交换
*
* @param array
* @return
*/
public static List<List<Integer>> getAllPermutations(int[] array,List<List<Integer>> list,int start){
if(start == array.length){//遍历到最后一个
List<Integer> item = new ArrayList<Integer>(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<List<Integer>> permutations(int[] array,List<List<Integer>> list){
//将原数组加入结果集
List<Integer> item = new ArrayList<Integer>();
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<Integer> nextPermutation(int[] nums){
if(nums == null)
return null;
if(nums.length == 0)
return new ArrayList<Integer>();
//长度为1的数组
if (nums.length == 1) {
return new ArrayList<Integer>(nums[0]);
}
//存储结果
List<Integer> result = new ArrayList<Integer>(); //从后向前找到第一个不满足逆序的元素
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;
}
46. 47. Permutations and Permutations II 都适用(Java,字典序 + 非字典序排列)的更多相关文章
- java和javax都是Java的API包,java是核心包,javax的x是extension的意思,也就是扩展包。
java和javax都是Java的API包,java是核心包,javax的x是extension的意思,也就是扩展包.
- Servlet和JSP中的过滤器都是Java类
JSP 过滤器 Servlet和JSP中的过滤器都是Java类,它们存在的目的如下: 在请求访问后端资源时拦截它 管理从服务器返回给客户端的响应 下面列出了多种常用的过滤器类型: 认证过滤器 数据压缩 ...
- 为什么大家都说Java中只有值传递?
最近跟Java中的值传递和引用传递杠上了,一度怀疑人生.查了很多资料,加上自己的理解,终于搞清楚了,什么是值传递和引用传递.也搞明白了,为什么大家都说Java只有值传递,没有引用传递.原来,我一直以来 ...
- leetcode46. Permutations 、47. Permutations II、 剑指offer字符串的排列
字符串排列和PermutationsII差不多 Permutations第一种解法: 这种方法从0开始遍历,通过visited来存储是否被访问到,level代表每次已经存储了多少个数字 class S ...
- 46. 47. Permutations
求全排列. 1. 无重复元素 Given a collection of distinct numbers, return all possible permutations. For example ...
- [LeetCode] “全排列”问题系列(一) - 用交换元素法生成全排列及其应用,例题: Permutations I 和 II, N-Queens I 和 II,数独问题
一.开篇 Permutation,排列问题.这篇博文以几道LeetCode的题目和引用剑指offer上的一道例题入手,小谈一下这种类型题目的解法. 二.上手 最典型的permutation题目是这样的 ...
- “全排列”问题系列(一)[LeetCode] - 用交换元素法生成全排列及其应用,例题: Permutations I 和 II, N-Queens I 和 II,数独问题
转:http://www.cnblogs.com/felixfang/p/3705754.html 一.开篇 Permutation,排列问题.这篇博文以几道LeetCode的题目和引用剑指offer ...
- Permutations and Permutations II
Permutations 问题:给定一个无重复元素的数组,输出其中元素可能的所有排列 示例: 输入:[2,3,4] 输出:[ [2,3,4], [2,4,3], [3,2,4], [3,4,2], [ ...
- LeetCode39/40/22/77/17/401/78/51/46/47/79 11道回溯题(Backtracking)
LeetCode 39 class Solution { public: void dfs(int dep, int maxDep, vector<int>& cand, int ...
随机推荐
- P4782 【模板】2-SAT 问题
https://www.luogu.org/problemnew/show/P4782 链接 https://www.luogu.org/problemnew/show/P4782 思路 选a就必须选 ...
- Linux 题目收集
目录 1.库函数,系统调用,用户态及内核态 2.查看进程,杀死进程 3.查看文档 4.scp命令 5.不在 sudoers 文件中.此事将被报告 6.chmod: 更改"minikube&q ...
- MetInfo V5.1 GetShell一键化工具
# 漏洞解析: config/config.inc.php $langoks = $db->get_one("SELECT * FROM $met_lang WHERE lang='$ ...
- 【ContextLoaderListener】Web项目启动报错java.lang.ClassNotFoundException: ContextLoaderListener
错误原因: 进入到tomcat的部署路径.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\下检查了一下,发现工程部署后在WE ...
- C语言变量的作用域和存储类型
1.动态局部变量:也称局部变量.自动变量,是指在函数内部定义的自动变量,不带static修饰,作用域是定义该变量的子程序.在退出函数后,变量自带内存会自动释放. 2.静态局部变量:是指在函数内部定义的 ...
- input事件手机端可能会影响手写
<input type="text" oninput="this.value=this.value.trim()"> 这样会导致手写出现问题,一个字 ...
- Apple ID双重认证验证码无法输入问题
问题:用Apple ID登录老版本ios系统时,会提示“”需要提供Apple ID验证码才能登陆.请键入您的密码,并随后键入显示在您其他设备上的验证码”. 解决:老版本系统无输入验证码的地方,那就把验 ...
- Unity3D学习笔记(二十六):MVC框架下的背包系统(1)
MVC背包 需求: 1.背包格子的装备是可以拖动的 2.装备栏的装备也是可以拖动的 3.当背包格子的装备拖动到装备栏时,如果是装备类型和装备栏类型是一致的能装上 4.背包的装备是按照顺序放在格子中的, ...
- java.lang.NoClassDefFoundError: com/gexin/rp/sdk/exceptions/RequestException解决方法
本文为博主原创,未经允许不得转载: 最近在开发个推的时候遇到的问题,当我在maven仓库中下载个推的jar包时,下载不下来,索性在项目中Configue build Path,将jar下载到本地 手动 ...
- ABAP-FI常用BAPI
总帐会计: (比较简单全部测试通过,关帐时使用) Line item of document for ledger with summary table GL F: BAPI_GLX_GETDOCI ...