文章目录
- 剑指 Offer II 083. 没有重复元素集合的全排列|46. 全排列:
- 样例 1
- 样例 2
- 样例 3
- 提示
- 分析
- 题解
- 原题传送门:https://leetcode-cn.com/problems/VvJkup/
- 原题传送门:https://leetcode-cn.com/problems/permutations/
剑指 Offer II 083. 没有重复元素集合的全排列|46. 全排列:
给定一个不含重复数字的整数数组 nums
,返回其 所有可能的全排列 。可以 按任意顺序 返回答案。
样例 1
输入:
nums = [1,2,3]
输出:
[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
样例 2
输入:
nums = [0,1]
输出:
[[0,1],[1,0]]
样例 3
输入:
nums = [1]
输出:
[[1]]
提示
- 1 <= nums.length <= 6
- -10 <= nums[i] <= 10
- nums 中的所有整数 互不相同
分析
- 这道算法题采用递归,回溯法比较简单,谁要是非要用循环非递归,二当家的佩服。
- 提示中说每个数字各不相同,那我们全排列就可以考虑成数字所在位置或者说是数组的下标的不同排列,因为数字都不同,所以我们就不必关心每个数字是几了。
- 可以单开辟空间存储中间排列,这样我们需要能判断某个数字是否被选择过,可以用hash表存储当前排列结果,然后去看是否含有当前数字,但是这样似乎比较低效。
- 每个位置的数字都不一样,所以我们直接存储一下某个位置的数字是否被使用即可。
- 可以直接使用一个布尔数组存储访问过的位置,但是提示中说数字个数最多6个,那我们最多用6个二进制位就可以表示所有数字的已使用和未使用,一个 int 型变量足以,我们用这个 int 型变量的二进制位变化,去对应数字的已使用和未使用。
- 也可以直接在原数组用交换的方式模拟排列,每个数字在所有位置上都排一次不就是全排列吗?先轮着放第一个位置,然后轮着放第二个位置,以此类推。
题解
java
不使用交换的方式
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> ans = new ArrayList<>();
dfs(nums, new ArrayList<>(nums.length), 0, ans);
return ans;
}
private void dfs(int[] nums, List<Integer> row, int flag, List<List<Integer>> ans) {
if (row.size() == nums.length) {
ans.add(new ArrayList<>(row));
return;
}
for (int i = 0; i < nums.length; ++i) {
if (((flag >> i) & 1) == 0) {
row.add(nums[i]);
dfs(nums, row, flag | (1 << i), ans);
row.remove(row.size() - 1);
}
}
}
}
使用交换的方式
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> ans = new ArrayList<>();
backtrack(nums, 0, ans);
return ans;
}
private void backtrack(int[] nums, int cur, List<List<Integer>> ans) {
if (cur == nums.length) {
ans.add(Arrays.stream(nums).boxed().collect(Collectors.toList()));
return;
}
// 当前位置保持不变,接着排下一个
backtrack(nums, cur + 1, ans);
// 换后面的某一个到当前位置
for (int i = cur + 1; i < nums.length; ++i) {
swap(nums, cur, i);
backtrack(nums, cur + 1, ans);
swap(nums, cur, i);
}
}
private void swap(int[] nums, int a, int b) {
nums[a] ^= nums[b];
nums[b] ^= nums[a];
nums[a] ^= nums[b];
}
}
c
/\*\*
\* Return an array of arrays of size \*returnSize.
\* The sizes of the arrays are returned as \*returnColumnSizes array.
\* Note: Both returned array and \*columnSizes array must be malloced, assume caller calls free().
\*/
int\*\* permute(int\* nums, int numsSize, int\* returnSize, int\*\* returnColumnSizes){
\*returnSize = numsSize;
for (int i = 2; i < numsSize; ++i) {
\*returnSize \*= i;
}
int \*\*ans = (int \*\*) malloc(sizeof(int \*) \* (\*returnSize));
\*returnColumnSizes = (int \*) malloc(sizeof(int) \* (\*returnSize));
for (int i = 0; i < \*returnSize; ++i) {
ans[i] = (int \*) malloc(sizeof(int) \* numsSize);
(\*returnColumnSizes)[i] = numsSize;
}
int ansSize = 0;
backtrack(nums, numsSize, 0, ans, &ansSize);
return ans;
}
void backtrack(int\* nums, int numsSize, int cur, int \*\*ans, int \*ansSize) {
if (cur == numsSize) {
for (int i = 0; i < numsSize; ++i) {
ans[\*ansSize][i] = nums[i];
}
\*ansSize += 1;
return;
}
// 当前位置保持不变,接着排下一个
backtrack(nums, numsSize, cur + 1, ans, ansSize);
// 换后面的某一个到当前位置
for (int i = cur + 1; i < numsSize; ++i) {
swap(nums, cur, i);
backtrack(nums, numsSize, cur + 1, ans, ansSize);
swap(nums, cur, i);
}
}
void swap(int\* nums, int a, int b) {
nums[a] ^= nums[b];
nums[b] ^= nums[a];
nums[a] ^= nums[b];
}
c++
class Solution {
private:
void backtrack(vector<int> &nums, int cur, vector<vector<int>> &ans) {
if (cur == nums.size()) {
ans.push\_back(nums);
return;
}
// 当前位置保持不变,接着排下一个
backtrack(nums, cur + 1, ans);
// 换后面的某一个到当前位置
for (int i = cur + 1; i < nums.size(); ++i) {
swap(nums[cur], nums[i]);
backtrack(nums, cur + 1, ans);
swap(nums[cur], nums[i]);
}
}
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> ans;
backtrack(nums, 0, ans);
return ans;
}
};
python
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
n = len(nums)
ans = []
def backtrack(cur: int) -> None:
if cur == n:
ans.append(nums[:])
return
# 当前位置保持不变,接着排下一个
backtrack(cur + 1)
# 换后面的某一个到当前位置
for i in range(cur + 1, n):
还有兄弟不知道网络安全面试可以提前刷题吗?费时一周整理的160+网络安全面试题,金九银十,做网络安全面试里的显眼包!
王岚嵚工程师面试题(附答案),只能帮兄弟们到这儿了!如果你能答对70%,找一个安全工作,问题不大。
对于有1-3年工作经验,想要跳槽的朋友来说,也是很好的温习资料!
【完整版领取方式在文末!!】
***93道网络安全面试题***
![](https://img-blog.csdnimg.cn/img_convert/6679c89ccd849f9504c48bb02882ef8d.png)
![](https://img-blog.csdnimg.cn/img_convert/07ce1a919614bde78921fb2f8ddf0c2f.png)
![](https://img-blog.csdnimg.cn/img_convert/44238619c3ba2d672b5b8dc4a529b01d.png)
内容实在太多,不一一截图了
### 黑客学习资源推荐
最后给大家分享一份全套的网络安全学习资料,给那些想学习 网络安全的小伙伴们一点帮助!
对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。
😝朋友们如果有需要的话,可以联系领取~
#### 1️⃣零基础入门
##### ① 学习路线
对于从来没有接触过网络安全的同学,我们帮你准备了详细的**学习成长路线图**。可以说是**最科学最系统的学习路线**,大家跟着这个大的方向学习准没问题。
![image](https://img-blog.csdnimg.cn/img_convert/acb3c4714e29498573a58a3c79c775da.gif#pic_center)
##### ② 路线对应学习视频
同时每个成长路线对应的板块都有配套的视频提供:
![image-20231025112050764](https://img-blog.csdnimg.cn/874ad4fd3dbe4f6bb3bff17885655014.png#pic_center)
#### 2️⃣视频配套工具&国内外网安书籍、文档
##### ① 工具
![](https://img-blog.csdnimg.cn/img_convert/d3f08d9a26927e48b1332a38401b3369.png#pic_center)
##### ② 视频
![image1](https://img-blog.csdnimg.cn/img_convert/f18acc028dc224b7ace77f2e260ba222.png#pic_center)
##### ③ 书籍
![image2](https://img-blog.csdnimg.cn/img_convert/769b7e13b39771b3a6e4397753dab12e.png#pic_center)
资源较为敏感,未展示全面,需要的最下面获取
![在这里插入图片描述](https://img-blog.csdnimg.cn/e4f9ac066e8c485f8407a99619f9c5b5.png#pic_center)![在这里插入图片描述](https://img-blog.csdnimg.cn/111f5462e7df433b981dc2430bb9ad39.png#pic_center)
##### ② 简历模板
![在这里插入图片描述](https://img-blog.csdnimg.cn/504b8be96bfa4dfb8befc2af49aabfa2.png#pic_center)
**因篇幅有限,资料较为敏感仅展示部分资料,添加上方即可获取👆**
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化资料的朋友,可以点击这里获取](https://bbs.csdn.net/topics/618540462)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**