NC+LC:全排列

无重复项

题目描述
给定一个不含重复数字的数组nums,返回其 所有可能的全排列
LeetCode中可按任意顺序返回答案,但牛客要求以数字在数组中的位置靠前为优先级,按字典序排列输出。
示例
输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

思路


实现代码1

class Solution {
    public List<List<Integer>> permute(int[] nums) {
        List<List<Integer>> res = new ArrayList<List<Integer>>(); //结果集合
        List<Integer> list = new ArrayList<>();
        for(int num : nums){ //将数组元素存入集合,直接对该集合进行处理
            list.add(num);
        }
        backtrack(res, nums.length, list, 0);
        return res;
    }
    public void backtrack(List<List<Integer>> res, int length, List<Integer> list, int start) {
        if (start == length) { //递归终止条件,遍历到了数组末尾
            res.add(new ArrayList<Integer>(list)); //需新建一个集合对象存入
            return;
        }
        for (int i = start; i < length; i++) {
            //将start上的元素依次与后面的元素进行交换
            Collections.swap(list, start, i);
            //递归
            backtrack(res, length, list, start+1);
            //回溯上一个start的位置,保证与其他位置进行同样的交换
            Collections.swap(list, start, i);
        }
    }
}

实现代码2

使用类似深度优先遍历(DFS)的做法
class Solution {
    public List<List<Integer>> permute(int[] nums) {
        List<List<Integer>> res = new ArrayList<List<Integer>>(); //结果集合
        int[] visited = new int[nums.length]; //标记访问过的位置
        backtrack(res, nums, new ArrayList<Integer>(), visited);
        return res;
    }
    public void backtrack(List<List<Integer>> res, int[] nums, ArrayList<Integer> tmp, int[] visited) {
        if (tmp.size() == nums.length) { //递归终止条件
            res.add(new ArrayList<>(tmp));
            return;
        }
        for (int i = 0; i < nums.length; i++) {
            if (visited[i] == 1) continue;
            visited[i] = 1;
            tmp.add(nums[i]);
            //递归访问没访问过的位置
            backtrack(res, nums, tmp, visited);
            //在回溯过程中还原到上一状态
            visited[i] = 0;
            tmp.remove(tmp.size() - 1);
        }
    }
}

有重复项

题目描述
给定一个可包含重复数字的序列nums,按任意顺序 返回所有不重复的全排列。
示例
输入:nums = [1,1,2]
输出:[[1,1,2],[1,2,1],[2,1,1]]

思路

回溯法(在题目LC 46.全排列的基础进行修改,修改1:先将数组进行排序,使重复元素聚集在一起;修改2:接着通过判断当前元素与前一个元素是否相等,且前一元素是否被访问过来决定是否进行排列)
重点代码:
if (i > 0 && nums[i] == nums[i-1] && visited[i-1] == 0){
    continue;
}

实现代码

class Solution {
    public List<List<Integer>> permuteUnique(int[] nums) {
        List<List<Integer>> res = new ArrayList<List<Integer>>(); //结果集合
        int[] visited = new int[nums.length]; //标记访问过的位置
        Arrays.sort(nums); //排序,这样重复元素会聚集在一起
        backtrack(res, nums, new ArrayList<Integer>(), visited);
        return res;
    }
    public void backtrack(List<List<Integer>> res, int[] nums, ArrayList<Integer> tmp, int[] visited) {
        if (tmp.size() == nums.length) { //递归终止条件,遍历到了数组末尾
            res.add(new ArrayList<>(tmp));
            return;
        }
        for (int i = 0; i < nums.length; i++) {
            //若当前元素与前一个元素相等,且前一元素未被访问过,就直接跳过,避免重复排列
            if (i > 0 && nums[i] == nums[i-1] && visited[i-1] == 0){
                continue;
            }
            if(visited[i] == 0){
                visited[i] = 1;
                tmp.add(nums[i]);
                //递归访问没访问过的位置
                backtrack(res, nums, tmp, visited);
                //在回溯过程中还原到上一状态
                visited[i] = 0;
                tmp.remove(tmp.size() - 1);
            }
        }
    }
}

全部评论

相关推荐

01-17 18:15
已编辑
门头沟学院 前端工程师
从上午约我面试然后他迟到,然后中午发消息打电话给我说重约面试时间,我就该意识到。【管理不规范,只是这家公司最小的问题】他妈一个不是技术的人来给我技术面。。。连vvue什么?连react是什么?连普通的HTTP请求是什么?这些东西都不懂的人来给我做技术面,我真的。。。。他妈浪费我40分钟。。一天面了三场,这家公司属实牛逼。不停的问我说上班下班时间谁来派任务公司在哪个区发展怎么样,公司的管理模式什么样,培养机制怎么样带教负责什么。如果出bug了谁来负责。我真的求你了别闹了。我答了15分钟,我已经很不想回答了。然后他就问了我一些很招笑的面试问题。问我前端框架架构设计怎么设计,Websocket可以实现SSE吗??最后还要我硬说,为什么我们公司没转正?为什么?为什么?我说我怎么知道。。这是领导决定,又不是我决定,他说让我分析一下。。。我真的草了,这个人是来搞我的吗?我最后问我说这个没有技术面,他说他就是技术面虽然我今天面的另外两家也很逆天。一个人不停的吹牛,自己100人的公司是全国前几,吹牛了一个小时。我中途几次想跑,真的是底下玩手机在听他那吹牛。。然后最后来了句说,我承诺的东西要实现哦,不然的话,公司会追责的,我我请问我承诺了什么?从头到尾也没有说让我承诺什么。而且我只是作为一个小小的前端卡拉咪,应届生。我要承担什么??好崩溃。。好崩溃的,一天面了三场。两家1000-9999的公司。面试官问的都很傻逼,甚至有些东西我问他估计都答不出来。。&nbsp;我这是在干嘛呀?浪费我一天的时间,我的奶奶。。我本来是抱着说我很菜,我要面试中发现自己的问题,现在来看他妈的这三场面试,面试本身就是问题。。
点赞 评论 收藏
分享
行云流水1971:这份实习简历的优化建议: 结构清晰化:拆分 “校园经历”“实习经历” 板块(当前内容混杂),按 “实习→校园→技能” 逻辑排版,求职意向明确为具体岗位(如 “市场 / 运营实习生”)。 经历具象化:现有描述偏流程,需补充 “动作 + 数据”,比如校园活动 “负责宣传” 可加 “运营公众号发布 5 篇推文,阅读量超 2000+,带动 300 + 人参与”;实习内容补充 “协助完成 XX 任务,效率提升 X%”。 岗位匹配度:锚定目标岗位能力,比如申请运营岗,突出 “内容编辑、活动执行” 相关动作;申请市场岗,强化 “资源对接、数据统计” 细节。 信息精简:删减冗余表述(如重复的 “负责”),用短句分点,比如 “策划校园招聘会:联系 10 + 企业,组织 200 + 学生参与,到场率达 85%”。 技能落地:将 “Office、PS” 绑定经历,比如 “用 Excel 整理活动数据,输出 3 份分析表;用 PS 设计 2 张活动海报”,避免技能单独罗列。 优化后需强化 “经历 - 能力 - 岗位需求” 的关联,让实习 / 校园经历的价值更直观。 若需要进一步优化服务,私信
实习,投递多份简历没人回...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务