【问题标题】:how to understand this recursion in the leecode?如何理解 leetcode 中的这种递归?
【发布时间】:2021-11-10 05:14:55
【问题描述】:

java新手,我在leecode中阅读了答案,它要求一个像[1,2,3]这样的数组并返回它的排列[1,3,2],[2,1,3].. ...并感到困惑,尤其是这段代码

Collections.swap(output, first, i);
backtrack(n, output, res, first + 1);

我不知道为什么使用 Collections.swap(output,first,i) 我认为在第一个循环中,第一个和 i 等于 0,所以为什么在这里使用交换。它们是相同的价值。这个递归实际上是做什么的,我调试它并无法弄清楚。代码如下:

package com.company;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

 class Main {

public static void main(String[] args) {
    int[]arr=new int[]{1,2,3};
    Main main1=new Main();
    List<List<Integer>> lists = main1.permute(arr);
    System.out.println(lists);

}

   public List<List<Integer>> permute(int[] nums) {
       List<List<Integer>> res = new ArrayList<List<Integer>>();

       List<Integer> output = new ArrayList<Integer>();
       for (int num : nums) {
           output.add(num);
       }

       int n = nums.length;
       backtrack(n, output, res, 0);
       return res;
   }

   public void backtrack(int n, List<Integer> output, List<List<Integer>> res, int first) {
       
       if (first == n) {
           res.add(new ArrayList<Integer>(output));
       }
       for (int i = first; i < n; i++) {
           
           Collections.swap(output, first, i);
          
           backtrack(n, output, res, first + 1);
          
           Collections.swap(output, first, i);
       }
   }
}

【问题讨论】:

  • 你问Collections.swap做什么?
  • @c0der 我对排列感到困惑,Navaneeth Sen 明确了 Collections.swap,但我不知道排列中的方法
  • Navaneeth Sen 明确 Collections.swap 如果 @Navaneeth Sen 的回答对您有帮助,请考虑对其进行投票。见stackoverflow.com/help/someone-answers
  • @c0der 好的,但我需要一些时间来阅读您的代码
  • 每次我使用 backtrack(n, output, res, first + 1) 然后它转到函数 backtrck ,所以它是 Collections.swap(output, first, i);和拳头 =i 因为 for 循环中的“int i = first”。那么为什么要得到 [1,2,3] > 交换到 [1,3,2]。大声笑.....

标签: java algorithm recursion


【解决方案1】:

这是一个稍微简化和注释的版本,可能有助于遵循代码的作用:

import java.util.*;

public class Main   {

    public static void main(String[] args) {
        int[]arr=new int[]{1,2,3};
        List<List<Integer>> permutations = new Main().permute(arr);
        System.out.println(permutations);
    }

       public List<List<Integer>> permute(int[] nums) {

           List<List<Integer>> result = new ArrayList<>();
           List<Integer> input = new ArrayList<>();
           for (int num : nums) {
               input.add(num);
           }

           backtrack(input, result, 0);
           return result;
       }

       public void backtrack(List<Integer> input, List<List<Integer>> result, int currentIndex) {

           if (currentIndex == input.size() ) { //index passed the end of the collection
               result.add(new ArrayList<>(input)); //add the permutation to the returned result
               //the method return here because when currentIndex == input.size()
               //next for loop will not be executed
               //you may add a return here. It may improve the readability of the code
           }

           //iterate over each element of the array form currentIndex to the end
           for (int i = currentIndex; i < input.size(); i++) {

               Collections.swap(input, currentIndex, i);//create a permutation by swapping

               backtrack(input, result, currentIndex + 1); //increment currentIndex and process new permutation

               Collections.swap(input, currentIndex, i);//undo permutation before next loop
           }
       }
}

【讨论】:

  • 似乎最后一个“Collections.swap(input, currentIndex, i);//undo permutation before next loop”永远不会执行
  • backtrack(input, result, currentIndex + 1); 返回时它确实如此。添加一个简单的打印输出以查看。
【解决方案2】:

根据documentation,java.util.Collections类的swap()方法用于交换指定列表中指定位置的元素。 如果指定位置相等,则调用此方法保持列表不变。

因此,在递归技术中,即使在特定条件下什么都不做,也可以进行调用,只是为了使逻辑更易于实现和理解。如果您想避免这种情况,您将不必要地需要将条件语句带入逻辑中,这实际上不是必需的。

【讨论】:

  • 但是,我发现回溯中的每个递归(n,output,res,first+1),Collection.swap(output,first,i) 都会得到相同的结果。为什么这会使排列成功?
  • 它交换到列表中的元素以获得新的排列。例如 [1,2,3] > 换成 [1,3,2]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-15
  • 2012-11-08
  • 1970-01-01
  • 2016-10-14
  • 2018-03-28
  • 1970-01-01
  • 2016-11-15
相关资源
最近更新 更多