所有唯一排列 - 堆栈溢出问题

时间:2016-10-14 01:37:08

标签: java algorithm stack-overflow

我正在尝试解决以下问题:

  

给定可能包含重复项的数字集合,返回   所有可能的独特排列。

这是我的代码:

public class Solution {
    public ArrayList<ArrayList<Integer>> permute(ArrayList<Integer> a) {
        HashMap<ArrayList<Integer>, Boolean> unique = new HashMap<>();
        ArrayList<ArrayList<Integer>> results = new ArrayList<>();
        permu(results, a, 0, unique);
        return results;
    }

    private void permu(ArrayList<ArrayList<Integer>> results, final ArrayList<Integer> a, int item, HashMap<ArrayList<Integer>, Boolean> unique) {
        for(int i = 0; i < a.size(); i++) {
            ArrayList<Integer> aClone = new ArrayList<>(a);
            // swap
            int backup = aClone.get(i);
            aClone.set(i, aClone.get(item));
            aClone.set(item, backup);
            if(!unique.containsKey(aClone)) {
                results.add(aClone);
                unique.put(aClone, true);
                permu(results, aClone, i, unique); //<--- Stack overflow error
            }

        }
    }
}

我在重复调用第(19)行

时遇到堆栈溢出错误

1 个答案:

答案 0 :(得分:1)

好吧,我不想破坏好面试的问题,但是这个问题很有趣,所以...

这是一个超级L337的答案,可以非常快速地生成所有独特的排列,而无需使用太多内存或堆栈。如果你在求职面试中使用它,面试官会要求你解释它是如何工作的。如果你能做到,那么你应该得到它:)

请注意,我在列表中置换了字符而不是列表中的整数,只是因为它更容易打印出结果。

import java.util.Arrays;
import java.util.function.Consumer;


public class UniquePermutations
{
    static void generateUniquePermutations(String s, Consumer<String> consumer)
    {
        char[] array = s.toCharArray();
        Arrays.sort(array);
        for (;;)
        {
            consumer.accept(String.valueOf(array));

            int changePos=array.length-2;
            while (changePos>=0 && array[changePos]>=array[changePos+1])
                --changePos;

            if (changePos<0)
                break; //all done

            int swapPos=changePos+1;
            while(swapPos+1 < array.length && array[swapPos+1]>array[changePos])
                ++swapPos;

            char t = array[changePos];
            array[changePos] = array[swapPos];
            array[swapPos] = t;

            for (int i=changePos+1, j = array.length-1; i < j; ++i,--j)
            {
                t = array[i];
                array[i] = array[j];
                array[j] = t;
            }
        }
    }

    public static void main (String[] args) throws java.lang.Exception
    {
        StringBuilder line = new StringBuilder();
        generateUniquePermutations("banana", s->{
            if (line.length() > 0)
            {
                if (line.length() + s.length() >= 75)
                {
                    System.out.println(line.toString());
                    line.setLength(0);
                }
                else
                    line.append(" ");
            }
            line.append(s);
        });
        System.out.println(line);
    }
}

这是输出:

aaabnn aaanbn aaannb aabann aabnan aabnna aanabn aananb aanban aanbna
aannab aannba abaann abanan abanna abnaan abnana abnnaa anaabn anaanb
anaban anabna ananab ananba anbaan anbana anbnaa annaab annaba annbaa
baaann baanan baanna banaan banana bannaa bnaaan bnaana bnanaa bnnaaa
naaabn naaanb naaban naabna naanab naanba nabaan nabana nabnaa nanaab
nanaba nanbaa nbaaan nbaana nbanaa nbnaaa nnaaab nnaaba nnabaa nnbaaa