有一个比较有趣的问题如下:
假如有五个数字,12345,请列出所有的排列,结果不能重复.
分析:
对于此类排列问题,优先想到递归的方式去处理,那么把问题转换成算法呢?
首先,假如只有三个数字123
那么排列如下
1 -> 23
-> 32
2 -> 13
-> 31
3 -> 12
-> 21
很明显,在最后两个数字时,只需要将它们颠倒一下即可,然后递归结束。刚开始进入递归算法时,列出所有的第一个数字,然后在循环里去调用递归。
实现:
时间复杂度:
首先递归中有双重循环,那么复杂度是N^2.
在递归中,假如3个数字是3次,4个数字是4*3次,可见递归的复杂度是N!
根据算法时间复杂度原则,只保留最高阶,所以该算法的时间复杂度是O(N!)
算法分析中常见的复杂度
O(1) < O(lgn) < O(n) < O(nlgn) < O(n2)< O(n3)<O(2n) < O(n!) < O(nn)
假如有五个数字,12345,请列出所有的排列,结果不能重复.
分析:
对于此类排列问题,优先想到递归的方式去处理,那么把问题转换成算法呢?
首先,假如只有三个数字123
那么排列如下
1 -> 23
-> 32
2 -> 13
-> 31
3 -> 12
-> 21
很明显,在最后两个数字时,只需要将它们颠倒一下即可,然后递归结束。刚开始进入递归算法时,列出所有的第一个数字,然后在循环里去调用递归。
实现:
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class ArrangeNumber {
// Added this set for avoiding repetition result;
private static Set<String> set = new HashSet<String>();
/**
* @param args
*/
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(2);
list.add(4);
arrangeNumbers("", list);
}
public static void arrangeNumbers(String header, List<Integer> list) {
// If there are only two elements, display them positive order and negative order, the Recursion method ended
if(list.size() == 2) {
if(!set.contains(header + list.get(0) + list.get(1))) {
System.out.println(header + list.get(0) + list.get(1));
set.add(header + list.get(0) + list.get(1));
}
if(!set.contains(header + list.get(1) + list.get(0))) {
System.out.println(header + list.get(1) + list.get(0));
set.add(header + list.get(1) + list.get(0));
}
return;
}
// Main Recursion logic
for(int i = 0; i < list.size(); i ++) {
List<Integer> templist = new ArrayList<Integer>();
String tempheader = header + list.get(i);
for(int j = 0; j < list.size(); j ++) {
if(i != j) {
templist.add(list.get(j));
}
}
arrangeNumbers(tempheader, templist);
}
}
}
时间复杂度:
首先递归中有双重循环,那么复杂度是N^2.
在递归中,假如3个数字是3次,4个数字是4*3次,可见递归的复杂度是N!
根据算法时间复杂度原则,只保留最高阶,所以该算法的时间复杂度是O(N!)
算法分析中常见的复杂度
O(1) < O(lgn) < O(n) < O(nlgn) < O(n2)< O(n3)<O(2n) < O(n!) < O(nn)