Search code examples
pythonpermutationdepth-first-searchmutableletter

strange way of working in DFS in one of leetcode questions


I think this is just about some fundamental difference about Python function and data structure but I wasn't able to figure out why the method II doesn't working it seems the variable res also change values during the traverse but just not as expected, can anyone tell me why.

Method 1:

class Solution:
    def numTilePossibilities(self, tiles: str) -> int:
        
        n=len(tiles)
        d={}
        for e in tiles:
            d[e]=d.get(e,0)+1
            
        s=''
        res=[0]   ## only difference
        self._help(d,s,res,n)
        return res[0]
        
    def _help(self,d,s,res,n):

        if len(s)<n:
            for e in d:
                if d[e]>0:
                    d[e]-=1
                    res[0]+=1
                    print(s)
                    print(res)
                    self._help(d,s+e,res,n)
                    d[e]+=1

Method 2:

class Solution:
    def numTilePossibilities(self, tiles: str) -> int:
        
        n=len(tiles)
        d={}
        for e in tiles:
            d[e]=d.get(e,0)+1
            
        s=''
        res=0
        self._help(d,s,res,n)
        return res 0
        
    def _help(self,d,s,res,n):

        if len(s)<n:
            for e in d:
                if d[e]>0:
                    d[e]-=1
                    res+=1
                    print(s)
                    print(res)
                    self._help(d,s+e,res,n)
                    d[e]+=1

Solution

  • You're passing an array in the first one, the second one is an int.

    This'd simply pass through:

    class Solution:
        def numTilePossibilities(self, tiles):
            frequencies = collections.Counter(tiles)
            product = 1
            for f in frequencies.values():
                product *= -~f
    
            possibles = 0
            for num in range(1, product):
                digits = []
                for f in frequencies.values():
                    digits.append(num % -~f)
                    num //= -~f
                temp = math.factorial(sum(digits))
                for digit in digits:
                    temp //= math.factorial(digit)
                possibles += temp
    
            return possibles
    

    class Solution:
        def numTilePossibilities(self, tiles):
            frequencies = collections.Counter(tiles)
            product = 1
            for f in frequencies.values():
                product *= (f + 1)
    
            possibles = 0
            for num in range(1, product):
                digits = []
                for f in frequencies.values():
                    digits.append(num % -~f)
                    num //= (f + 1)
                temp = math.factorial(sum(digits))
                for digit in digits:
                    temp //= math.factorial(digit)
                possibles += temp
    
            return possibles
    

    References

    • For additional details, you can see the Discussion Board. There are plenty of accepted solutions with a variety of languages and explanations, efficient algorithms, as well as asymptotic time/space complexity analysis1, 2 in there.