【Leetcode】Permutations

来源:互联网 发布:eplan软件 64位 编辑:程序博客网 时间:2024/04/30 22:04

【题目】

Given a collection of numbers, return all possible permutations.

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].


【分析】

感觉这道题目就是一个比较典型的回溯,backtracking.

从简单的情况入手,规律就非常清晰了。

比如:[1]情况就一种

[1,2]的时候就是2 在[1]的基础上,两个位置进行插入:

[1,2],[2,1]

[1,2,3]的时候,就是在前者的基础上每个情况的三个位置插入

所以个数 = n * (Pres)

两层循环,对于上一个所有序列遍历(每一种排序)

第二层,针对这个序列,n个位置插入,形成新的小list.


*注意: liat a = b 会造成b 把地址一起赋给a了, 有任何改变的话都会影响彼此。

所以赋值要只赋值有两种情况:

1).a = b.clone()

2) a = new ArrayList(b)

【代码】

我的通过的代码,感谢自己认真调处来了,没有放弃。。。主要也是看不太懂别人的。


考虑两种base的情况,=1和=0的时候

然后就是对于一个长度为n的情况,

首先用一个数组拷贝到前n-1个,最后一个留作left,等前n-1个排序完毕之后,就可以等着插入了。

当然插入前,还要保存前n-1个的排序结果

里面有很多细节需要注意。

public class Solution {    public List<List<Integer>> permute(int[] num) {        ArrayList<List<Integer>> result = new ArrayList<List<Integer>>(); if(num.length == 0 ) return result;  //base else if (num.length == 1) {   //base ArrayList<Integer> inner = new ArrayList<Integer>();<span style="white-space:pre"></span> inner.add(num[0]);<span style="white-space:pre"></span> result.add(inner);<span style="white-space:pre"></span> return result;  }  else{ int n = num.length-1; int[] next= new int[n]; int left = num[n]; System.arraycopy(num,0, next, 0, n);List<List<Integer>> tmp = permute(next);//用来存储前n-1个的排序 for (List<Integer> list : tmp) { int length = list.size();  for(int i=0;i<=length;i++){ ArrayList<Integer> tmplist = new ArrayList<Integer>(); //这里要采用一个临时存储的list,并且每次循环都要重新赋值,否则就会累计叠加。 tmplist = new ArrayList<Integer>(list); tmplist.add(i,left); result.add(tmplist); } } return result;  }    }}


【其他答案】

一样,感觉好清晰好优化,只需要加一轮循环。

public List<List<Integer>> permute(int[] num) {    LinkedList<List<Integer>> res = new LinkedList<List<Integer>>();    res.add(new ArrayList<Integer>());    for (int n : num) {        int size = res.size(); //必须要记录下res的此时的size,因为之后每次循环以后都在加减元素。        for (; size > 0; size--) {            List<Integer> r = res.pollFirst(); //返回并且移除第一个元素 ,上一轮的每一种排序            for (int i = 0; i <= r.size(); i++) {                List<Integer> t = new ArrayList<Integer>(r);                t.add(i, n);                res.add(t);            }        }    }    return res;}



和我的做做法一样,直接不需要递归了, 加一轮循环搞定。


    public List<List<Integer>> permute(int[] num) {        List<List<Integer>> wrapList = new LinkedList<List<Integer>>();        List<List<Integer>> preList = null;        List<Integer> subList = new LinkedList<Integer>();        if(num.length == 0) return wrapList;
        subList.add(num[0]);        wrapList.add(subList);        preList = wrapList;
        for(int i=1; i<num.length; i++) {            wrapList = new LinkedList<List<Integer>>();            for(int j=0; j<preList.size(); j++) {                for(int k=0; k<=preList.get(j).size(); k++) {                    subList = new LinkedList<Integer>(preList.get(j));                    subList.add(k, num[i]);                    wrapList.add(subList);                }            }            preList = wrapList;        }        return wrapList;    }


0 0
原创粉丝点击