1

I am looking at the code for Permutations problem on leetcode. For example, [1,2,3] have the following permutations: [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], and [3,2,1]. And I found there is one sentence

ArrayList<Integer> temp = new ArrayList<Integer>(l);

I have no idea why here needs to assign the "l" to "temp". And I tried current.add(l) direclty but gave me the wrong answer. Can you help me with this?

public class Solution {

    public ArrayList<ArrayList<Integer>> permute(int[] num) {
        ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();

        //start from an empty list
        result.add(new ArrayList<Integer>());

        for (int i = 0; i < num.length; i++) {
            //list of list in current iteration of the array num
            ArrayList<ArrayList<Integer>> current = new ArrayList<ArrayList<Integer>>();

            for (ArrayList<Integer> l : result) {
                // # of locations to insert is largest index + 1
                for (int j = 0; j < l.size()+1; j++) {
                    // + add num[i] to different locations
                    l.add(j, num[i]);
                    ArrayList<Integer> temp = new ArrayList<Integer>(l);

                    current.add(temp);

                    //System.out.println(temp);

                    // - remove num[i] add
                    l.remove(j);
                }
            }

            result = new ArrayList<ArrayList<Integer>>(current);
        }

        return result;
    }
}
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
Qiang
  • 1,468
  • 15
  • 18

2 Answers2

3

I have no idea why here needs to assign the "l" to "temp"

He's not - that would just be:

ArrayList<Integer> temp = l;

Instead, the code creates a copy of the content of the list l refers to, in a new ArrayList. That means that future changes to the list that l refers to (such as the call to l.remove(j) immediately afterwards) don't affect the new list.

As a simple stand-alone example of that, consider:

List<String> original = new ArrayList<>();
original.add("foo");
List<String> copy = new ArrayList<>(original);
System.out.println(copy.size()); // 1
original.add("bar");
System.out.println(copy.size()); // Still 1

Admittedly the code is written in a very odd manner - until the final statement, result only ever has a single element, so iterating over it is pretty pointless - but I believe that explains the single statement you were asking about.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • so creating the "temp" is to avoid further modification to "l". Thus I can still write like " current.add(l)" if there is no "l.remove(j)",right? And that explains the "add" method is just copy the reference rather than object into the ArrayList, am I right? – Qiang Jun 05 '14 at 06:26
  • @Qiang: Your comment isn't very clear, but I *suspect* you have the right idea now. – Jon Skeet Jun 05 '14 at 06:27
  • Thank you for you kindness. I've been struggling for this for a long time :) – Qiang Jun 05 '14 at 06:31
  • eh.... sry for bothering u again. But I got a new problem. since "add" method is to invoke reference "temp" to ArrayList "current". However, in the next iteration. the temp is directed to another new object. Does this not change the previous added "temp" ? – Qiang Jun 05 '14 at 06:40
  • @Qiang: again, I don't understand your comment - but I suggest you ask it as a new, separate question with a short but complete example demonstrating the problem. – Jon Skeet Jun 05 '14 at 07:13
  • I figured it out :) and I illustrated using an image in other questions [ArrayList](http://stackoverflow.com/questions/7080546/add-an-object-to-an-arraylist-and-modify-it-later/24054213#24054213) – Qiang Jun 05 '14 at 07:35
2

If you did

current.add(l);

you would be adding the same reference to the ArrayList l to current. So, if you made some changes in one of those lists, both would be modified. In order to avoid that issue, in the line

ArrayList<Integer> temp = new ArrayList<Integer>(l);

you are creating a different ArrayList but with the same content. So, they will be different objects (different references).

Christian Tapia
  • 33,620
  • 7
  • 56
  • 73
  • thank you for your answering. I know where I made mistake. the "add" method is just copying the reference rather than object to the ArrayList. So further modification to "l" would affect the "current". – Qiang Jun 05 '14 at 06:28