美文网首页
Leetcode 47 全排列 II

Leetcode 47 全排列 II

作者: itbird01 | 来源:发表于2022-01-01 22:34 被阅读0次
    题目.png

    题意:给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。

    解法:
    1.审题可知,其实就是回溯算法的应用
    2.排列组合的回溯算法实现
    3.和上一题的区别是,有重复元素,涉及到重复元素,我们首先想到的是在回溯过程中如何剪枝
    4.可以声明used数组,代表每个数字是否被访问过,同时负责数据已排序,来解决剪枝

    回溯算法理解

    概念

    回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。许多复杂的,规模较大的问题都可以使用回溯法,有“通用解题方法”的美称。

    回溯其实也是一种递归,有以下四个参数,当然不一定是我所举例的类型,要看题目而定一个全局变量集合保存所有满足条件的答案,举例:List<List<Integer>> list,一个集合保存一个满足条件的答案,举例:List<Integer> tempList,算法问题给所给的输入条件,这个可能是一个字符串,也可能是一个数组

    总结

    此题解法的理解,其实就是for循环,从0开始,递归遍历,以1开头的所有情况,遍历过程中,需要判断当前解中是否含有当前元素了,如果含有,则继续。然后判断以2开头的所有情况。直到数组末尾元素为头的情况遍历完成。
    回溯算法的

    ##解法1
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    class Solution {
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        List<Integer> temp = new ArrayList<Integer>();
    
        public List<List<Integer>> permuteUnique(int[] nums) {
            boolean[] used = new boolean[nums.length];
            Arrays.sort(nums);
            backSearch(used, nums);
            return ans;
        }
        private void backSearch(boolean[] used, int[] nums) {
            if (temp.size() == nums.length) {
                ans.add(new ArrayList<Integer>(temp));
                return;
            }
    
            for (int i = 0; i < nums.length; i++) {
                if (used[i] || (i > 0 && nums[i] == nums[i - 1] && !used[i - 1])) {
                    continue;
                }
    
                temp.add(nums[i]);
                used[i] = true;
                backSearch(used, nums);
                used[i] = false;
                temp.remove(temp.size() - 1);
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:Leetcode 47 全排列 II

          本文链接:https://www.haomeiwen.com/subject/aymiqrtx.html