leetcode第46题

简介: 这是自己开始想到的一个方法,考虑的思路是,先考虑小问题怎么解决,然后再利用小问题去解决大问题。没错,就是递归的思路。比如说,如果只有 1 个数字 [ 1 ],那么很简单,直接返回 [ [ 1 ] ] 就 OK 了。如果加了 1 个数字 2, [ 1 2 ] 该怎么办呢?我们只需要在上边的情况里,在 1 的空隙,也就是左边右边插入 2 就够了。变成 [ [ 2 1 ], [ 1 2 ] ]。

image.png

描述的很简单,就是给定几个数,然后输出他们所有排列的可能。

解法一 插入

这是自己开始想到的一个方法,考虑的思路是,先考虑小问题怎么解决,然后再利用小问题去解决大问题。没错,就是递归的思路。比如说,

如果只有 1 个数字 [ 1 ],那么很简单,直接返回 [ [ 1 ] ] 就 OK 了。

如果加了 1 个数字 2, [ 1 2 ] 该怎么办呢?我们只需要在上边的情况里,在 1 的空隙,也就是左边右边插入 2 就够了。变成 [ [ 2 1 ], [ 1 2 ] ]。

如果再加 1 个数字 3,[ 1 2 3 ] 该怎么办呢?同样的,我们只需要在上边的所有情况里的空隙里插入数字 3 就行啦。例如 [ 2 1 ] 在左边,中间,右边插入 3 ,变成 3 2 1,2 3 1,2 1 3。同理,1 2 在左边,中间,右边插入 3,变成 3 1 2,1 3 2,1 2 3,所以最后的结果就是 [ [ 3 2 1],[ 2 3 1],[ 2 1 3 ], [ 3 1 2 ],[ 1 3 2 ],[ 1 2 3 ] ]。

如果再加数字也是同样的道理,只需要在之前的情况里,数字的空隙插入新的数字就够了。

思路有了,直接看代码吧。

publicList<List<Integer>>permute(int[] nums) {
returnpermute_end(nums,nums.length-1);
}
// end 表示当前新增的数字的位置privateList<List<Integer>>permute_end(int[] nums, intend) {
// 只有一个数字的时候if(end==0){
List<List<Integer>>all=newArrayList<>();
List<Integer>temp=newArrayList<>();
temp.add(nums[0]);
all.add(temp);
returnall;
    }
//得到上次所有的结果List<List<Integer>>all_end=permute_end(nums,end-1);
intcurrent_size=all_end.size();
//遍历每一种情况for (intj=0; j<current_size; j++) { 
//在数字的缝隙插入新的数字for (intk=0; k<=end; k++) {
List<Integer>temp=newArrayList<>(all_end.get(j));
temp.add(k, nums[end]);
//添加到结果中all_end.add(temp);
        };
    }
//由于 all_end 此时既保存了之前的结果,和添加完的结果,所以把之前的结果要删除for (intj=0; j<current_size; j++) {
all_end.remove(0);
    }
returnall_end;
}

既然有递归的过程,我们也可以直接改成迭代的,可以把递归开始不停压栈的过程省略了。

publicList<List<Integer>>permute(int[] nums) {
List<List<Integer>>all=newArrayList<>();
all.add(newArrayList<>());
//在上边的基础上只加上最外层的 for 循环就够了,代表每次新添加的数字for (inti=0; i<nums.length; i++) {
intcurrent_size=all.size();
for (intj=0; j<current_size; j++) {
for (intk=0; k<=i; k++) {
List<Integer>temp=newArrayList<>(all.get(j));
temp.add(k, nums[i]);
all.add(temp);
            }
        }
for (intj=0; j<current_size; j++) {
all.remove(0);
        }
    }
returnall;
}

时间复杂度,如果只分析代码的话挺复杂的。如果从最后的结果来说,应该是 n! 个结果,所以时间复杂度应该是 O(n!)。

空间复杂度:O(1)

这道题很经典了,用动态规划,回溯,递归各实现了一遍,当然解法一强行递归了一下,和解法三相比真是相形见绌,解法三才是原汁原味的递归,简洁优雅。


相关文章
|
4月前
leetcode-1518:换酒问题
leetcode-1518:换酒问题
28 0
|
4月前
|
算法
leetcode:389. 找不同
leetcode:389. 找不同
21 0
|
4月前
leetcode-827:最大人工岛
leetcode-827:最大人工岛
53 0
|
4月前
|
Java
leetcode-474:一和零
leetcode-474:一和零
32 0
顺手牵羊(LeetCode844.)
好多同学说这是双指针法,但是我认为叫它顺手牵羊法更合适
67 0
leetcode 827 最大人工岛
leetcode 827 最大人工岛
56 0
leetcode 827 最大人工岛
|
Python
LeetCode 1904. 你完成的完整对局数
一款新的在线电子游戏在近期发布,在该电子游戏中,以 刻钟 为周期规划若干时长为 15 分钟 的游戏对局。这意味着,在 HH:00、HH:15、HH:30 和 HH:45 ,将会开始一个新的对局,其中 HH 用一个从 00 到 23 的整数表示。游戏中使用 24 小时制的时钟 ,所以一天中最早的时间是 00:00 ,最晚的时间是 23:59 。
97 0
LeetCode 389. 找不同
给定两个字符串 s 和 t,它们只包含小写字母。
64 0
|
算法
leetcode第42题
也就是红色区域中的水, 数组是 height = [ 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 ] 。 原则是高度小于 2,temp ++,高度大于等于 2,ans = ans + temp,temp = 0。 temp 初始化为 0 ,ans 此时等于 2。 height [ 0 ] 等于 0 < 2,不更新。 height [ 1 ] 等于 1 < 2,不更新。 height [ 2 ] 等于 0 < 2, 不更新。 height [ 3 ] 等于 2 >= 2, 开始更新 height [ 4 ] 等于 1 < 2,temp = temp + 1 = 1。 h
leetcode第42题
|
人工智能 算法
leetcode第41题
对于这种要求空间复杂度的,我们可以先考虑如果有一个等大的空间,我们可以怎么做。然后再考虑如果直接用原数组怎么做,主要是要保证数组的信息不要丢失。目前遇到的,主要有两种方法就是交换和取相反数。
leetcode第41题