【LeetCode】Permutations 解题报告
全排列问题。经常使用的排列生成算法有序数法、字典序法、换位法(Johnson(Johnson-Trotter)、轮转法以及Shift cursor cursor* (Gao & Wang)法。
【题目】
Given a collection of numbers, return all possible permutations.
For example,
[1,2,3]
have the following permutations:
[1,2,3]
, [1,3,2]
, [2,1,3]
, [2,3,1]
, [3,1,2]
,
and [3,2,1]
.
【暴力递归】
这是比較直观的思路。可是也有要注意的地方。刚開始写的时候,没有注意到list是共用的。所曾经面得到的答案后面会改掉而导致错误。
public class Solution {
List<List<Integer>> ret = new ArrayList<List<Integer>>(); public List<List<Integer>> permute(int[] num) {
int len = num.length;
if (len == 0) return ret; List<Integer> list = new ArrayList<Integer>();
run(list, num);
return ret;
} public void run(List<Integer> list, int[] num) {
if (list.size() == num.length) {
//注意这里要又一次new一个list。要不然后面会被改动
List<Integer> res = new ArrayList<Integer>();
res.addAll(list);
ret.add(res);
return;
}
for (int i = 0; i < num.length; i++) {
if (list.contains(num[i])) {
continue;
}
list.add(num[i]);
run(list, num);
list.remove(list.indexOf(num[i])); //不要忘记这一步
}
}
}
【字典序法】
C++的STL库里面有nextPermutation()方法。事实上现就是字典序法。
下图简单明了地介绍了字典序法
归纳一下为:
比如,1234的全排列例如以下:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGppYWJpbg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
【代码实现】
因为Java的list传參传的是地址,所以每次加入时都要记得又一次new一个新的list加入到结果集中。否则加入到结果集中的原list会被后面的操作改变。
public class Solution {
public List<List<Integer>> permute(int[] num) {
List<List<Integer>> ret = new ArrayList<List<Integer>>(); int len = num.length;
if (len == 0) return ret; Arrays.sort(num); //字典序法需先对数组升序排序 //数组转为list
List<Integer> list0 = new ArrayList<Integer>();
for (int i = 0; i < len; i++) {
list0.add(num[i]);
} //把原始数组相应的list加入到结果中。不能直接加入list0,由于后面它会一直变化
List<Integer> ll = new ArrayList<Integer>();
ll.addAll(list0);
ret.add(ll); //逐次找下一个排列
for (int i = 1; i < factorial(len); i++) {
ret.add(nextPermutation(list0));
}
return ret;
} /***字典序法生成下一个排列***/
public List<Integer> nextPermutation(List<Integer> num) {
//找到最后一个正序
int i = num.size()-1;
while(i > 0 && num.get(i-1) >= num.get(i)){
i--;
} //找到最后一个比num[i-1]大的数
int j = i;
while(j < num.size() && num.get(j) > num.get(i-1)) {
j++;
} //交换num[i-1]和num[j-1]
int tmp = num.get(i - 1);
num.set(i - 1, num.get(j - 1));
num.set(j - 1, tmp); //反转i以后的数
reverse(num, i, num.size()-1); List<Integer> ret = new ArrayList<Integer>();
ret.addAll(num);
return ret;
} public void reverse(List<Integer> list, int begin, int end) {
for(int i = begin, j = end; i < j; i++) {
list.add(i, list.remove(j));
}
} public int factorial(int n) {
return (n == 1 || n == 0) ? 1 : factorial(n - 1) * n;
}
}
上面的实现须要先对原数组升序排序。以下对nextPermutation(List<Integer> num)改进后就不用对num排序了。
/***字典序法生成下一个排列***/
public List<Integer> nextPermutation(List<Integer> num) {
//找到最后一个正序
int i = num.size()-1;
while(i > 0 && num.get(i-1) >= num.get(i)){
i--;
} //有了这个推断就不用num最初是按升序排好的了
if (i == 0) {
reverse(num, 0, num.size()-1);
List<Integer> ret = new ArrayList<Integer>();
ret.addAll(num);
return ret;
} //找到最后一个比num[i-1]大的数
int j = i;
while(j < num.size() && num.get(j) > num.get(i-1)) {
j++;
} //交换num[i-1]和num[j-1]
int tmp = num.get(i - 1);
num.set(i - 1, num.get(j - 1));
num.set(j - 1, tmp); //反转i以后的数
reverse(num, i, num.size()-1); List<Integer> ret = new ArrayList<Integer>();
ret.addAll(num);
return ret;
}
欢迎高人对上述代码继续优化!
相关题目:【LeetCode】Next Permutation 解题报告 和 【LeetCode】Permutations II 解题报告
【LeetCode】Permutations 解题报告的更多相关文章
- LeetCode: Permutations 解题报告
Permutations Given a collection of numbers, return all possible permutations. For example,[1,2,3] ha ...
- 【LeetCode】46. Permutations 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 解题方法 方法一:库函数 方法二:递归 方法三:回溯法 日期 题目地址:h ...
- leetcode—Palindrome 解题报告
1.题目描述 Given a string s, partition s such that every substring of the partition is a palindrome. Ret ...
- LeetCode C++ 解题报告
自己做得LeetCode的题解,使用C++语言. 说明:大多数自己做得,部分参考别人的思路,仅供参考; GitHub地址:https://github.com/amazingyyc/The-Solut ...
- C++版 - 剑指offer之面试题37:两个链表的第一个公共结点[LeetCode 160] 解题报告
剑指offer之面试题37 两个链表的第一个公共结点 提交网址: http://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46?t ...
- LeetCode: Subsets 解题报告
Subsets Given a set of distinct integers, S, return all possible subsets. Note: Elements in a subset ...
- LeetCode: Triangle 解题报告
Triangle Given a triangle, find the minimum path sum from top to bottom. Each step you may move to a ...
- LeetCode: isSameTree1 解题报告
isSameTree1 Given two binary trees, write a function to check if they are equal or not. Two binary t ...
- LeetCode: Combinations 解题报告
Combinations Given two integers n and k, return all possible combinations of k numbers out of 1 ... ...
随机推荐
- Python MySQLdb select(选择) 封装
对MySQL选择的封装 def select_data(sql): conn = MySQLdb.connect(host="10.10.10.77", user="xx ...
- django -- model中只有Field类型的数据才能成为数据库中的列
一.model的定义: from django.db import models # Create your models here. class Person(models.Model): firs ...
- 关于Server Tomcat v8.0 Server at localhost failed to start的解决办法
测试环境: Eclipse Java EE IDE for Web Developers. Version: Luna Service Release 1 (4.4.1)Build id: 20140 ...
- Web Component探索
概述 各种网站往往需要一些相同的模块,比如日历.调色板等等,这种模块就被称为“组件”(component).Web Component就是网页组件式开发的技术规范. 采用组件进行网站开发,有很多优点. ...
- html5+css3 权威指南阅读笔记(三)---表单及其它新增和改良元素
一.新增元素及属性 1.表单内元素的form属性. html5: <form id="testForm"> <input type=text> </f ...
- LeetCode——4Sum & 总结
LeetCode--4Sum & 总结 前言 有人对 Leetcode 上 2Sum,3Sum,4Sum,K Sum问题作了总结: http://blog.csdn.net/nanjunxia ...
- zabbix web 登录成功后提示(红色提示):zabbix server is not running:the information displayed may not be current
原因是$ZBX_SERVER,我配了外网地址,这里应该配成内网的: # cat /etc/zabbix/web/zabbix.conf.php <?php // Zabbix GUI confi ...
- Checkbox: ListView 与CheckBox 触发事件冲突的问题
我相信很多人都遇到过 ListView 中放入checkBox ,会导致ListView的OnItemClickListener无效,这是怎么回事呢? 这是因为checkBox 的点击事件的优先级比L ...
- Windows: 打开关闭网络连接的方法
在Cmd中键入 netsh interface set interface name="本地连接" admin=disablednetsh interface set interf ...
- (原创)c++11改进我们的模式之改进单例模式
我会写关于c++11的一个系列的文章,会讲到如何使用c++11改进我们的程序,本次讲如何改进我们的模式,会讲到如何改进单例模式.观察者模式.访问者模式.工厂模式.命令模式等模式.通过c++11的改进, ...