Listing all permutations of a string/integer

后端 未结 29 1993
没有蜡笔的小新
没有蜡笔的小新 2020-11-22 00:44

A common task in programming interviews (not from my experience of interviews though) is to take a string or an integer and list every possible permutation.

Is there

29条回答
  •  名媛妹妹
    2020-11-22 01:28

    Here is the simplest solution I can think of:

    let rec distribute e = function
      | [] -> [[e]]
      | x::xs' as xs -> (e::xs)::[for xs in distribute e xs' -> x::xs]
    
    let permute xs = Seq.fold (fun ps x -> List.collect (distribute x) ps) [[]] xs
    

    The distribute function takes a new element e and an n-element list and returns a list of n+1 lists each of which has e inserted at a different place. For example, inserting 10 at each of the four possible places in the list [1;2;3]:

    > distribute 10 [1..3];;
    val it : int list list =
      [[10; 1; 2; 3]; [1; 10; 2; 3]; [1; 2; 10; 3]; [1; 2; 3; 10]]
    

    The permute function folds over each element in turn distributing over the permutations accumulated so far, culminating in all permutations. For example, the 6 permutations of the list [1;2;3]:

    > permute [1;2;3];;
    val it : int list list =
      [[3; 2; 1]; [2; 3; 1]; [2; 1; 3]; [3; 1; 2]; [1; 3; 2]; [1; 2; 3]]
    

    Changing the fold to a scan in order to keep the intermediate accumulators sheds some light on how the permutations are generated an element at a time:

    > Seq.scan (fun ps x -> List.collect (distribute x) ps) [[]] [1..3];;
    val it : seq =
      seq
        [[[]]; [[1]]; [[2; 1]; [1; 2]];
         [[3; 2; 1]; [2; 3; 1]; [2; 1; 3]; [3; 1; 2]; [1; 3; 2]; [1; 2; 3]]]
    

提交回复
热议问题