0

I wrote this function but i'm not sure about the time complexity of it. I have my guesses but i wont include them. here is the code sample.

function generateAllPerms(s: string) {
    const result: string[] = []
    function perm(curr: string[] = [], sArr: string[]) {
        if (sArr.length == 0) result.push(curr.join(''))
        else {
            for (let i = 0; i < sArr.length; i++) {
                let k = sArr[i]
                curr.push(k)
                sArr.splice(i, 1)
                perm(curr, sArr)
                curr.pop()
                sArr.splice(i, 0, k)
            }
        }
    }
    perm([], [...s])
    return (result)
}

P.S: is there a way to improve its time complexity ?

In JS...

function generateAllPerms(s) {
    const result = []
    function perm(curr = [], sArr) {
        if (sArr.length == 0) result.push(curr.join(''))
        else {
            for (let i = 0; i < sArr.length; i++) {
                let k = sArr[i]
                curr.push(k)
                sArr.splice(i, 1)
                perm(curr, sArr)
                curr.pop()
                sArr.splice(i, 0, k)
            }
        }
    }
    perm([], [...s])
    return (result)
}

console.log(generateAllPerms('abc'))
danh
  • 62,181
  • 10
  • 95
  • 136
kataya1
  • 76
  • 2
  • 6
  • This problem has a complexity at least Ω(n.n!), for a string of n distinct characters. Compare to your findings. –  Aug 09 '22 at 19:58
  • 2
    I'm inclined to close this as a duplicate of [this question](https://stackoverflow.com/q/39125471/2887218) unless you can articulate why this one is especially distinct. – jcalz Aug 09 '22 at 20:05
  • @jcalz It might be similar but It's in another language. it uses backtracking so it will have a different space complexity. it generates the permutation rather than just counting them which will result in a different time complexity. I don't need to go relearn another language to have my questions answered maybe it's also a duplicate of something written in haskell or x86 asembly. – kataya1 Aug 09 '22 at 20:49
  • 2
    Your function doesn't seem to work, unfortunately. If I call `generateAllPerms("abcde")` I get `["ab", "cd", "e"]`. – jcalz Aug 09 '22 at 21:46
  • @jcalz you are correct. it's the line `perm(curr, sArr.splice(i, 1))` it should be `perm(curr, sArr)` instead. I just edited the code sample to fix it. Thank you. – kataya1 Aug 11 '22 at 00:41
  • So, we know that just to print/store the output requires n×n! operations. Pragmatically speaking this means any computer is going to bomb out when n is quite small, so I doubt it matters whether your particular algorithm is O(n×n!) vs O(n²×n!) etc. You need to decide what the complexity of your base operations are; most of the stuff you're doing is O(1) but `a.splice(i,...)` is probably O(`a.length-i`) and `a.join()` and `[...a]` is O(`a.length`). I imagine this still puts you at O(n×n!); the only thing I can imagine improving is... – jcalz Aug 11 '22 at 01:54
  • ... to replace `splice()` with linked list operations to be O(1) instead of O(array length), but that's still O(n×n!) and this probably doesn't do much of use, I'd think. Maybe your computer could produce 15! instead of 14! that way? Anyway does this constitute an answer if I write it up or do you want something more concrete, like [this](https://tsplay.dev/w6PAem) which estimates your algorithm as approximately (n+6)×n! - 6n steps, which is just O(n×n!) – jcalz Aug 11 '22 at 01:58
  • I think you're right. – kataya1 Aug 11 '22 at 02:02
  • And [here](https://tsplay.dev/WPREJN) is a version using linked list operations to replace `splice()`; but I don't know if that's any better in any meaningful way, given that there's a bit of overhead to set up and walk the list. It's still essentially (n×n!). Let me know how you'd like to proceed with an answer. – jcalz Aug 11 '22 at 02:18
  • Is there a way to make all the permutation with a time less than O(n!) ? – kataya1 Aug 11 '22 at 18:38
  • No; as I said: "we know that just to print/store the output requires n×n! operations." There are n! permutations of n characters each; the *output* is of length n×n!. Unless you don't actually need to enumerate all the permutations, you're going to take n×n! operations at a bare minimum. Does that make sense? I will write up an answer here sometime soon-ish unless you have some reason why the above isn't sufficient. – jcalz Aug 11 '22 at 20:26

0 Answers0