recursion

作者: cookyo | 来源:发表于2019-07-19 17:09 被阅读0次

22 Generate Parentheses

class Solution:
    def generateParenthesis(self, n: int) -> List[str]:
        if n == 0:
            return []
        self.res = []
        self.solution('', n, n)
        return self.res
       
    def solution(self, s, left_n, right_n):
        if left_n == 0 and right_n == 0:
            self.res.append(s)
        if left_n > right_n or left_n < 0 or right_n < 0:
            return
        self.solution(s+'(', left_n - 1, right_n)
        self.solution(s+')', left_n, right_n - 1)

39 Combination Sum

'''
Example :
Input: candidates = [2,3,6,7], target = 7,
A solution set is:
[
  [7],
  [2,2,3]
]
'''
class Solution:
    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        if not candidates or not target:
            return []        
        res = []
        path = []        
        def dfs(candidates, target, tmp):
            if target < 0:
                return
            elif target == 0:
                res.append(tmp)
            else:
                for i in range(len(candidates)):
                    if candidates[i] <= target:
                        dfs(candidates[i:], target-candidates[i], tmp+[candidates[i]])       
                      
        dfs(candidates, target, [])
        return res

40 Combination Sum II

'''
Example :
Input: candidates = [10,1,2,7,6,1,5], target = 8,
A solution set is:
[
  [1, 7],
  [1, 2, 5],
  [2, 6],
  [1, 1, 6]
]
'''
class Solution:
    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
        if not candidates or not target:
            return []
        
        candidates = sorted(candidates)
        res = []
        path = []
        
        def dfs(candidates, target, tmp):
            if target < 0:
                return
            elif target == 0:
                if tmp not in res:
                    res.append(tmp)
            else:
                for i in range(len(candidates)):
                    if candidates[i] <= target:
                        dfs(candidates[i+1:], target-candidates[i], tmp+[candidates[i]])
        dfs(candidates, target, [])
        return res

46 Permutations

# 全排列
class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        if len(nums) == 0:
            return []
        self.res = []
        self.used = [False] * len(nums)
        self._dfs(nums, 0, [])
        return self.res
    
    def _dfs(self, nums, index, tmp):
        if index == len(nums):
            self.res.append(tmp)
            return 
        
        for i in range(len(nums)):
            if not self.used[i]:
                self.used[i] = True
                self._dfs(nums, index+1, tmp+[nums[i]])
                self.used[i] = False

47 Permutations II

'''
Input: [1,1,2]
Output:
[
  [1,1,2],
  [1,2,1],
  [2,1,1]
]
'''
class Solution:
    def permuteUnique(self, nums: List[int]) -> List[List[int]]:
        if len(nums) == 0:
            return []
        self.res = []
        self.used = [False] * len(nums)
        self._dfs(nums, 0, [])
        return self.res
    
    def _dfs(self, nums, index, tmp):
        if index == len(nums) and tmp not in self.res:
            self.res.append(tmp)
            return 
        
        for i in range(len(nums)):
            if not self.used[i]:
                self.used[i] = True
                self._dfs(nums, index+1, tmp+[nums[i]])
                self.used[i] = False

52 N-Queens II

class Solution:
    def totalNQueens(self, n: int) -> int:
        if n < 1:
            return 0
        self.count = 0
        self.cols = set()
        self.pie = set()
        self.na = set()
        self._dfs(n, 0)
        return self.count
    
    def _dfs(self, n, row):
        if row >= n:
            self.count += 1            
        for col in range(n):
            if col in self.cols or row+col in self.pie or row-col in self.na:
                continue
            self.cols.add(col)
            self.pie.add(row+col)
            self.na.add(row-col)
            self._dfs(n, row+1)
            self.cols.remove(col)
            self.pie.remove(row+col)
            self.na.remove(row-col)

55. Jump Game

'''
Input: [2,3,1,1,4]
Output: true
Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index.
'''
class Solution:
    def canJump(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        #贪心      
        # n = len(nums)
        # reach = 0
        # i = 0
        # while i <= reach and reach < n-1:
        #     reach = max(reach, nums[i] + i)
        #     i += 1
        # if reach >= n - 1:
        #     return True
        # else:
        #     return False
        
        #dp
        n = len(nums)
        dp = [0] * n
        dp[0] = 0
        
        for i in range(1, n):
            dp[i] = max(dp[i-1], nums[i-1]) - 1
            if dp[i] < 0:
                return False
        if dp[-1] >= 0:
            return True

67 Add Binary

'''
Example 1:

Input: a = "11", b = "1"
Output: "100"
Example 2:

Input: a = "1010", b = "1011"
Output: "10101"
'''
class Solution:
    # 递归
    def addBinary(self, a: str, b: str) -> str:
        if not a or not b:
            return a if a else b
        
        if a[-1] == '1' and b[-1] == '1':
            return self.addBinary(self.addBinary(a[:-1], b[:-1]), '1') + '0'
        elif a[-1] == '0' and b[-1] == '0':
            return self.addBinary(a[:-1], b[:-1]) + '0'
        else:
            return self.addBinary(a[:-1], b[:-1]) + '1'

77 Combinations

'''
Input: n = 4, k = 2
Output:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]
'''
class Solution:
    def combine(self, n: int, k: int) -> List[List[int]]:
        if n < 1:
            return []
        if k > n:
            return []        
        self.res = []
        self.dfs(n, k, 1, [])
        return self.res
    
    def dfs(self, n, k, start, tmp): #从start开始选,下次选只能选start后面的数
        if len(tmp) == k:
            self.res.append(tmp)
            return         
        for i in range(start, n+1):
            self.dfs(n, k, i+1, tmp+[i])

78 Subsets

'''
Input: nums = [1,2,3]
Output:
[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]
'''
class Solution(object):
    def subsets(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        res = []
        if len(nums) == 0:
            return res
        res.append([])
        for n in nums:
            temp = []
            for t in res:
                m = t + [n]
                temp.append(m)
            res = res + temp
        return res
#递归
class Solution(object):
    def subsets(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        if len(nums) == 0:
            return []
        res = []
        temp = []
        self.hs(nums, res, temp, 0)
        return res
    def hs(self, nums, res, temp, i):
        if i == len(nums):
            res.append(temp)
            return
        self.hs(nums, res, temp+[nums[i]], i+1)
        self.hs(nums, res, temp, i+1)

87 Scramble String

'''
Example 1:
Input: s1 = "great", s2 = "rgeat"
Output: true

Example 2:
Input: s1 = "abcde", s2 = "caebd"
Output: false
'''
class Solution:
    def isScramble(self, s1, s2):
        """
        :type s1: str
        :type s2: str
        :rtype: bool
        """
        if s1 == s2:
            return True
        if sorted(s1) != sorted(s2):
            return False
        length = len(s1)
        for i in range(1, length):
            if self.isScramble(s1[:i], s2[:i]) and self.isScramble(s1[i:], s2[i:]):
                return True
            if self.isScramble(s1[:i], s2[length - i:]) and self.isScramble(s1[i:], s2[:length - i]):
                return True
        return False

95 Unique Binary Search Trees II

'''
Example:
Input: 3
Output:
[
  [1,null,3,2],
  [3,2,null,1],
  [3,1,null,null,2],
  [2,1,3],
  [1,null,2,null,3]
]
Explanation:
The above output corresponds to the 5 unique BST's shown below:

   1         3     3      2      1
    \       /     /      / \      \
     3     2     1      1   3      2
    /     /       \                 \
   2     1         2                 3
'''
class Solution:
    def generateTrees(self, n: int) -> List[TreeNode]:
        if n == 0:
            return []
        return self.dfs(1, n)
    
    def dfs(self, left, right):
        if left > right:
            return [None]
        res = []
        for i in range(left, right + 1):
            leftNode = self.dfs(left, i-1)
            rightNode = self.dfs(i+1, right)
            for l_n in leftNode:
                for r_n in rightNode:
                    root = TreeNode(i)
                    root.left = l_n
                    root.right = r_n
                    res.append(root)

        return res

130 Surrounded Regions

'''
X X X X
X O O X
X X O X
X O X X
After running your function, the board should be:
X X X X
X X X X
X X X X
X O X X
'''
class Solution:
    # dfs
    def solve(self, board: List[List[str]]) -> None:
        """
        Do not return anything, modify board in-place instead.
        """
        def dfs(x, y):
            if x < 0 or x >= m or y < 0 or y >=n or board[x][y] != 'O': return
            board[x][y] = 'D'
            dfs(x-1, y)
            dfs(x+1, y)
            dfs(x, y-1)
            dfs(x, y+1)
            
        m = len(board)
        if m == 0: return
        n = len(board[0])
        for i in range(m):
            dfs(i, 0)
            dfs(i, n-1)
        for j in range(n):
            dfs(0, j)
            dfs(m-1, j)
        for i in range(m):
            for j in range(n):
                if board[i][j] == 'O':
                    board[i][j] = 'X'
                elif board[i][j] == 'D':
                    board[i][j] = 'O'

200 Number of Islands

# # method1 floodfill
# class Solution:
    
#     def numIslands(self, grid: List[List[str]]) -> int:
#         if not grid or not grid[0]:
#             return 0
        
#         self.dx = [-1, 1, 0, 0]
#         self.dy = [0, 0, -1, 1]
#         self.max_x = len(grid)
#         self.max_y = len(grid[0])
        
#         self.grid = grid
#         self.visited = set()
#         res = 0
#         for i in range(self.max_x):
#             for j in range(self.max_y):
#                 res += self.floodfill_dfs(i, j)
#         return res
    
#     def floodfill_dfs(self, x, y):
#         if not self._is_valid(x, y):
#             return 0
#         self.visited.add((x, y))
#         for k in range(4):
#             self.floodfill_dfs(x+self.dx[k], y+self.dy[k])
#         return 1
        
#     def _is_valid(self, x, y):
#         if x < 0 or x >= self.max_x or y < 0 or y >= self.max_y:
#             return False
#         if (x, y) in self.visited or self.grid[x][y] == '0':
#             return False
#         return True

# method2 UnionFind

class UnionFind():
    def init(self, grid):
        m, n = len(grid), len(grid[0])
        self.count = 0
        self.parent = [-1] * (m*n)
        self.rank = [0] * (m*n)
        for i in range(i):
            for j in range(j):
                if grid[i][j] = '1':
                    self.parent[i*n + j] = i*n + j
                    self.count += 1
                    
    def find(self, i):
        if self.parent[i] != i:
            self.parent[i] = self.find(parent[i])
        return self.parent[i]
    
    def union(self, i, j):
        rooti = self.find(i)
        rootj = self.find(j)
        
        if rooti != rootj:
            if self.rank[rooti] > self.rank[rootj]:
                self.parent[rootj] = rooti
            elif self.rank[rooti] < self.rank[rootj]:
                self.parent[rooti] = rootj
            else:
                self.parent[rooti] = rootj
                self.rank[rootj] += 1
            self.count -= 1

            
class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:     
        if not grid or not grid[0]:
            return 0
        uf = UnionFind(grid)
        directions = [(0,1),(0,-1),(1,0),(-1,0)]
        m, n = len(grid), len(grid[0])
        for i in range(m):
            for j in range(n):
                if grid[i][j] == '0':
                    continue
                for d in directions:
                    nr, nc = i+d[0], j+d[1]
                    if nr >= 0 and nc >= 0 and nr < m and nc < n and grid[i][j] == '1':
                        uf.union(i*n+j, nr*n+nc)
        return uf.count

212 Word Search II

# 回溯法会超时
#class Solution:
#     def findWords(self, board: List[List[str]], words: List[str]) -> List[str]:
        
#         self.res = []
#         num = len(words)
#         for i in range(num):
#             self.find(board, words[i])
#         return self.res
    
#     def find(self, board, word):
#         self.m = len(board)
#         self.n = len(board[0])
#         self.visited = set()
#         self.dir = [[0, 1], [0, -1], [1, 0], [-1, 0]]
#         for i in range(self.m):
#             for j in range(self.n):
#                 if board[i][j] == word[0]:
#                     tmp = word
#                     #self.dfs(board, i, j, word[1:], tmp)
#                     if self.dfs(board, i, j, word[1:], tmp):
#                         #print('res append word')
#                         if word not in self.res:
#                             self.res.append(word)
                    
#     def dfs(self, board, i, j, word, tmp):
#         if not word:
#             #print ('word length == 0')
#             #self.res.append(tmp)
#             return True
#         self.visited.add((i, j))
#         for d in self.dir:
#             #print (self.visited)
#             ni = i + d[0]
#             nj = j + d[1]
#             if not self.vaild(ni, nj) or board[ni][nj] != word[0]:
#                 continue
#             if self.dfs(board, ni, nj, word[1:], tmp):
#                 return True
#         self.visited.remove((i, j))
#         return False
        
            
#     def vaild(self, ni, nj):
#         if ni < 0 or nj < 0 or ni >= self.m or nj >= self.n or (ni, nj) in self.visited:
#             return False
#         return True
        
# 需要优化回溯算法以通过更大数据量的测试, 使用前缀树
class TrieNode:
    def __init__(self):
        self.children = {}
        self.Word = ''
        
class Solution:        
    def findWords(self, board: List[List[str]], words: List[str]) -> List[str]:
        m = len(board)
        if m == 0:
            return []
        n = len(board[0])
        trie = self.buildTrie(words)
        self.res = []
        for i in range(m):
            for j in range(n):
                self.DFS(board, i, j, trie)
        return self.res
    
    def DFS(self, board, i, j, trie):
        if trie.Word:
            self.res.append(trie.Word)
            trie.Word = ''
        if i<0 or i>=len(board) or j<0 or j>=len(board[0]) or not board[i][j] in trie.children:
            return
        tmp,board[i][j]=board[i][j],'X'
        for dx,dy in zip((-1,0,1,0),(0,-1,0,1)):
            self.DFS(board,i+dx,j+dy,trie.children[tmp])
        board[i][j]=tmp

        
    def buildTrie(self, words):
        trie = TrieNode()
        for word in words:
            cur = trie
            for c in word:
                if c not in cur.children: cur.children[c] = TrieNode()
                cur = cur.children[c]
            cur.Word = word
        return trie

403 Frog Jump

'''
[0,1,3,5,6,8,12,17]

There are a total of 8 stones.
The first stone at the 0th unit, second stone at the 1st unit,
third stone at the 3rd unit, and so on...
The last stone at the 17th unit.

Return true. The frog can jump to the last stone by jumping 
1 unit to the 2nd stone, then 2 units to the 3rd stone, then 
2 units to the 4th stone, then 3 units to the 6th stone, 
4 units to the 7th stone, and 5 units to the 8th stone.
'''
class Solution:
    def canCross(self, nums):
        """
        :type stones: List[int]
        :rtype: bool
        """
        stone={num:1 for num in nums}
        index=1
        k=1
        self.res={}
        return self.jump(stone,1,1,nums[-1])
    
    def jump(self,stone,index,k,n):
        if index==n:
            return True
        if index>n or (index not in stone) :
            return False
        if (index,k) in self.res:
            return self.res[(index,k)]
        if k==1:
            judge=self.jump(stone,index+k,k,n) or self.jump(stone,index+k+1,k+1,n)
            self.res[(index,k)]=judge
            return judge
        if k>1:
            judge= self.jump(stone,index+k,k,n) or self.jump(stone,index+k+1,k+1,n) or self.jump(stone,index+k-1,k-1,n)
            self.res[(index,k)]=judge
            return judge        

437 Path Sum III

'''
root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8

      10
     /  \
    5   -3
   / \    \
  3   2   11
 / \   \
3  -2   1

Return 3. The paths that sum to 8 are:
1.  5 -> 3
2.  5 -> 2 -> 1
3. -3 -> 11
'''
class Solution:
    def pathSum(self, root: TreeNode, sum: int) -> int:
        if root is None:
            return 0
        res = self.findpath(root, sum)
        res += self.pathSum(root.left, sum)
        res += self.pathSum(root.right, sum)
        return res
        
    def findpath(self, node, num):
        if node is None:
            return 0
        res = 0
        if node.val == num:
            res += 1
        res += self.findpath(node.left, num-node.val)
        res += self.findpath(node.right, num-node.val)
        return res

980 Unique Paths III

'''
On a 2-dimensional grid, there are 4 types of squares:
1 represents the starting square.  There is exactly one starting square.
2 represents the ending square.  There is exactly one ending square.
0 represents empty squares we can walk over.
-1 represents obstacles that we cannot walk over.

Input: [[1,0,0,0],[0,0,0,0],[0,0,2,-1]]
Output: 2
Explanation: We have the following two paths: 
1. (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2)
2. (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2)
'''
class Solution:
    def uniquePathsIII(self, grid: List[List[int]]) -> int:
        m = len(grid)
        n = len(grid[0])
        
        zeronum = 0
        
        for i in range(m):
            for j in range(n):
                if grid[i][j] == 0:
                    zeronum += 1
                    
        self.res = 0
        self.dir = [[0, 1], [0, -1], [-1, 0], [1, 0]]
        self.visited = set()
        #print(self.visited)
            
        for i in range(m):
            for j in range(n):
                if grid[i][j] == 1:
                    self.dfs(grid, i, j, zeronum, 0)
        return self.res
    
    def dfs(self, grid, i, j, zeronum, cnt):
        if grid[i][j] == 2 and cnt == zeronum:
            self.res += 1
        if (grid[i][j] == 0 or grid[i][j] == 1):
            self.visited.add((i, j))
            print(self.visited)
            for d in self.dir:
                nx = i + d[0]
                ny = j + d[1]
                if nx < 0 or ny < 0 or nx >= len(grid) or ny >= len(grid[0]) or grid[nx][ny] == -1 or (nx, ny) in self.visited:
                    continue
                if grid[i][j] == 0:
                    self.dfs(grid, nx, ny, zeronum, cnt+1)
                if grid[i][j] == 1:
                    self.dfs(grid, nx, ny, zeronum, cnt)
            self.visited.remove((i, j))

相关文章

  • Binary Tree and Recursion

    DFS Non-recursion (use stack) Recursion (自己调用自己)-- Traver...

  • Recursion

    How to calculate the complexity? How about the space?

  • Recursion

    Fibonacci Find the maximum value among array elements Bub...

  • Recursion

    发自简书 递归 导致递归的方法返回而没有再一次进行递归调用,此时我们称为基值情况( base case)。每一个递...

  • Recursion

    有限记忆和无限思维之间的矛盾促生了语言的递归性 语言是用有限手段生成无限话语的装置.如果一种语法没有递归机制,它将...

  • Recursion

    Fibonacci A frog can jump one or two steps at a time. How...

  • recursion

    22 Generate Parentheses 39 Combination Sum 40 Combination...

  • 递归

    recursion完成了iteration,但逻辑清晰,有以下问题: recursion 由stack完成,会溢出...

  • ZXAlgorithm - C5 DFS

    OutlineRecursionCombinationPermutationGraphNon-recursion ...

  • 递归(recursion)

    基线条件(base case)&递归条件(recursive case) 递归条件基线条件 堆栈 调用栈 递归调用栈

网友评论

      本文标题:recursion

      本文链接:https://www.haomeiwen.com/subject/bltrlctx.html