LeetCodeレトロスペクティブトピック46完全にランク付けされた問題解決策

質問の詳細

繰り返し番号のないシーケンスが与えられた場合、可能なすべての順列を返します。
例:

入力:[1,2,3]
出力:
[
[1,2,3
]、
[1,3,2]、
[2,1,3]、
[2,3,1 ]、[3,1,2 ]、
[3,2,1]
]

この質問は、比較的単純で古典的なバックトラッキングの質問、または順列と組み合わせの完全なリストです。この種の質問は、バックトラック(dfs + delete操作)によって完了することができます。この記事を書く目的は、バックトラッキングの一般的な記述を記録することです。 。、2つ目は、javaでの参照に注意を払う必要があることを思い出してください。

トピック分析

バックトラッキング問題の一般的な考え方は次のとおりです。

def backtrack(路径,选择列表)if满足条件:
          添加到最终结果
          return
      for 选择 in 选择列表:
             做选择
             backtrack(路径,选择列表)
             撤销选择

(これはLeetCodeのコメント領域で私が思うこと
です。@ Teki、それは良いことだと思います)コードを書くのは基本的にこの考えです。
ここで書いたコードは少し冗長です。実際、配列をマークせずにListのcontainsメソッドを直接使用できます(ここにマークを付けて、将来これを使用します)。通常、Javaはまだ少しだけ使用されているため、さびています。 。
コードを貼り付けます:

//有思路了,就是建立一个marked数组,记录标记情况,然后for循环,跳过标记的,然后一直往下搜索就行如
    //可以判断一下数组的和是否等于长度来判断是否完了
    //总体还是很简单的
    public List<List<Integer>> permute(int[] nums) {
    
    
        List<List<Integer>> results = new LinkedList<>();
        if(nums==null||nums.length==0)
            return results;

        for(int i=0;i<nums.length;i++)
        {
    
    
            int[] marked = new int[nums.length];
            backtrack(nums,i,marked,new LinkedList<Integer>(),results,0);
        }

        return results;
    }
    public void backtrack(int[] nums, int index, int[] marked, LinkedList<Integer> result, List<List<Integer>> results,int count){
    
    
        //count用于判断当前是否满了
        if(count==nums.length-1&&marked[index]==0){
    
    
            result.add(nums[index]);
            // System.out.println(result);
            results.add((List<Integer>)result.clone());//这里需要进行一个拷贝,不然里面存的都是一个变量,最后值都为0了
            result.remove(result.size()-1);
            return;
        }

        //判断当前索引是否被遍历过
        if(marked[index]==1)
            return;
        //如果都没有,则说明可以遍历
        //先把自己放进result中去
        result.add(nums[index]);
        marked[index]=1;
        count++;
        //再从头开始遍历
        for(int j=0;j<nums.length;j++)
            backtrack(nums,j,marked,result,results,count);
        //最终把自己删掉
//        System.out.println(nums[index]);
        result.remove(result.size()-1);
        marked[index]=0;
        count--;
    }

ここで、results.add((List<Integer>)result.clone());この行で最初に書いたのは、results.add(result)(バックトラックのために)最終的な出力結果がすべて空であるということでした。しばらく考えた後、これは基本型ではなく参照型であることを思い出しました。 、それを実行する必要があります一度コピーした後、リストのクローンを作成できないことがわかりました。しばらくチェックしたところ、LinkedListまたはArrayListしか使用できないことがわかり、強制的な型変換が必要でした。

おすすめ

転載: blog.csdn.net/qq_34687559/article/details/109090742