非c++ next_permutation方式
数组不可有重复值
时间复杂度 n^2 ✖ n! 好大!
思路:
nums = [1,2,3, 4]
先建立空lists 数量为n! = 4! = 24
[
[],
[],
[],
.
.
.
]
sPtr = 0
[1, 2, 3, 4]
3!=6次插入nums[sPtr]后,指针sPtr后移(超出回归0)
[
[1], // sPtr = 0
[1],
[1],
[1],
[1],
[1],
[2], // sPtr = 1
…
…
…
]
[1, 2, 3, 4]
插入前检测nums[sPtr] 是否已存在当前list中,是则指针sPtr后移(超出回归0)
2!=2次插入nums[sPtr]后,指针sPtr后移(超出回归0)
[
[
[1],[2] // sPtr = 1
[1],[2]
[1],[3] // sPtr = 2
[1],[3]
[1],[4] // sPtr = 3
[1],[4]
… // sPtr = 0
…
…
]
[1, 2, 3, 4]
插入前检测nums[sPtr] 是否已存在当前list中,是则指针sPtr后移(超出回归0)
1!=1次插入nums[sPtr]后,指针sPtr后移(超出回归0)
[
[1],[2],[3]
[1],[2],[4]
[1],[3],[2]
[1],[3],[4]
[1],[4],[2]
[1],[4],[3]
…
…
…
]
[1, 2, 3, 4]
插入前检测nums[sPtr] 是否已存在当前list中,是则指针sPtr后移(超出回归0)
0!=1次插入nums[sPtr]后,指针sPtr后移(超出回归0)
[
[1],[2],[3],[4]
[1],[2],[4],[3]
[1],[3],[2],[4]
[1],[3],[4],[2]
[1],[4],[2],[3]
[1],[4],[3],[2]
…
…
…
]
/*
* authur: Zefang Yu
* lastUpdate: 12:02 5/2/20
*/
public class Solution {
/*
* @param nums: A list of integers.
* @return: A list of permutations.
*/
public List<List<Integer>> permute(int[] nums) {
// write your code here
int len = nums.length;
int totalList = factorial(len);//总排列数量
List<List<Integer>> lists = new ArrayList<List<Integer>>();
// 在lists中建立空list
for(int i = 0; i < totalList; i++){
lists.add(new ArrayList<Integer>());
}
int sPtr = 0;// nums的指针index
//从所有排序的第一位开始排序,->第二位->..->最后一位
for(int i = 0; i < len; i++){
int factor = factorial(len-i-1);//当前位数在所有排列中出现的次数
//第一个list到最后一个list
for(int j = 0; j < totalList; j++){
//用完nums[sPtr]所有次数后,sPtr指针后移
if( j != 0 && (j%factor == 0)){
sPtr = (sPtr+1)%len;
}
//向所有空list(排列第一位时)中输入第一个数值时跳过判断
if(i != 0){
//判断当前list是否包含指针所指数值,包含则指针后移
while(lists.get(j).contains(nums[sPtr])){
sPtr = (sPtr+1)%len;
}
}
lists.get(j).add(nums[sPtr]);// 向当前list输入数值
}
}
System.out.println(lists);
return lists;
}
// return n!
public int factorial(int n){
int res = 1;
for(int i = 1; i <= n; i++){
res *= i;
}
return res;
}
}
改进思路:(可处理重复数)
基础思路同上,为处理重复数,加入时不加入数,而改为加入指针。
nums = [1,2,3, 4]
先建立空lists 数量为n! = 4! = 24
[
[],
[],
[],
.
.
.
]
sPtr = 0
[1, 2, 3, 4]
3!=6次插入sPtr后,指针sPtr后移(超出回归0)
[
0, // sPtr = 0
0,
0,r
0,
0,
0,
1, // sPtr = 1
…
…
…
]
[1, 2, 3, 4]
插入前检测sPtr 是否已存在当前list中,是则指针sPtr后移(超出回归0)
2!=2次插入sPtr后,指针sPtr后移(超出回归0)
[
[
0,1 // sPtr = 1
0,1
0,2 // sPtr = 2
0,2
0,3 // sPtr = 3
0,4
… // sPtr = 0
…
…
]
…
…
[1, 2, 3, 4]
插入前检测sPtr 是否已存在当前list中,是则指针sPtr后移(超出回归0)
0!=1次插入sPtr后,指针sPtr后移(超出回归0)
[
0,1,2,3
0,1,3,2
0,2,1,3
0,2,3,1
0,3,1,2
0,4,2,1
…
…
…
]
完成后使用循环将指针转换为实际数值