Leetcode刷题(20) 回溯实践

Leetcode刷题(19) 回溯实践

参考buladong的回溯算法最佳实践:括号生成

22. 括号生成

class Solution(object):
    def generateParenthesis(self, n):
        """
        :type n: int
        :rtype: List[str]
        """
        left = n
        right = n
        track = []
        res = []
        def backtrack(left, right, track):
            if left > right:
                return 
            if left < 0 or right < 0:
                return
            if left == 0 and right == 0:
                res.append("".join(track))
                return

            track.append('(')
            backtrack(left - 1, right, track)
            track.pop()

            track.append(')')
            backtrack(left, right - 1, track)
            track.pop()

        backtrack(n, n, track)
        return res
    

20. 有效的括号(虽然不是回溯的但是是括号系列的题目,我也一并放在这里了)

class Solution(object):
    def isValid(self, s):
        """
        :type s: str
        :rtype: bool
        """
        stack = []

        def convert(right):
            if right == ")":
                return "("
            elif right == "}":
                return "{"
            return "["

        for c in s:
            if c == "(" or c == "[" or c == "{":
                stack.append(c)
            else:
                left = convert(c) 
                if len(stack) > 0 and left == stack[-1]:
                    stack.pop()
                else:
                    return False

        if len(stack) == 0:
            return True
        else:
            return False

参考labuladong的回溯算法最佳实践: 解数独

37. 解数独

class Solution(object):
    def solveSudoku(self, board):
        """
        :type board: List[List[str]]
        :rtype: None Do not return anything, modify board in-place instead.
        """
        n = len(board[0])
        def isVaild(r, c, number):
            for i in range(n):
                if board[r][i] == str(number):
                    return False
                if board[i][c] == str(number):
                    return False
                if board[(r / 3) * 3 + i / 3][(c / 3) * 3 + i % 3] == str(number):
                    return False
            return True
                
        def backtrack(r, c):
            if r == n:
                return True
            if c == n:
                return backtrack(r + 1, 0)
            if board[r][c] != '.':
                return backtrack(r, c + 1)

            for number in range(1, 10):
                if not isVaild(r, c, number):
                    continue
                board[r][c] = str(number)
                if backtrack(r, c + 1):
                    return True
                board[r][c] = '.'

        backtrack(0, 0)

        

机器人的运动范围

# -*- coding:utf-8 -*-
# 注意这题的track的使用,记录了所有走过的路径且没有pop,
# 因为这是遍历整张图, 没有明确的终止条件(不像解数独,N皇后, 走迷宫)
class Solution:
    def __init__(self):
        self.count = 0
        self.track = []

    def movingCount(self, threshold, rows, cols):
        # write code here
        def isVaild(r, c):
            r = list(str(r))
            c = list(str(c))
            total = sum(list(map(int, r + c)))
            if threshold < total:
                return False
            else:
                return True

        def backtrack(r, c):
            if r >= rows or r < 0:
                return
            if c >= cols or c < 0:
                return
            # 防止走回头路进入死循环
            if (r, c) in self.track:
                return
            if isVaild(r, c):
                self.count += 1
                self.track.append((r, c))
                for d in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
                    backtrack(r + d[0], c + d[1])
        backtrack(0, 0)
        return self.count

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值