Leetcode 刷题笔记1 回溯算法part04

leetcode 491 递增子序列

这题的去重不能使用sort()对原数组进行排序,因为会破坏顺序。由于本题数组的长度为201,属于有限小数组,所以可以使用数组来做哈希。

class Solution:
    def findSubsequences(self, nums: List[int]) -> List[List[int]]:
        result = []
        self.backtracking(nums, 0, [], result)
        return result
    def backtracking(self, nums, startIndex, path, result):
        if len(path) > 1:
            result.append(path[:])
        uset = [0] * 201
        for i in range(startIndex, len(nums)):
            if (path and nums[i] < path[-1]) or uset[nums[i] + 100] == 1:
                continue
            path.append(nums[i])
            uset[nums[i] + 100] = 1
            self.backtracking(nums, i + 1, path, result)
            path.pop()

leetcode 46 全排列

本题的关键是在于如何去重,思路是使用一个used数组表示本层已经使用的元素。

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        result = []
        self.backtracking(nums, [False] * len(nums),[], result)
        return result
    def backtracking(self, nums, used, path, result):
        if len(path) == len(nums):
            result.append(path[:])
            return
        for i in range(len(nums)):
            if used[i]:
                continue
            used[i] = True
            path.append(nums[i])
            self.backtracking(nums, used, path, result)
            path.pop()
            used[i] = False

leetcode 47 全排列||

本题的关键还是去重,同树枝和同树层的去重用used数组的表示。

class Solution:
    def permuteUnique(self, nums: List[int]) -> List[List[int]]:
        result = []
        nums.sort()
        self.backtracking(nums, [False] * len(nums), [], result)
        return result
    def backtracking(self, nums, used, path, result):
        if len(path) == len(nums):
            result.append(path[:])
            return
        for i in range(len(nums)):
            if i > 0 and nums[i] == nums[i - 1] and not used[i - 1]:
                continue
            if not used[i]:
                used[i] = True
                path.append(nums[i])
                self.backtracking(nums, used, path, result)
                path.pop()
                used[i] = False

leetcode 332 重新安排行程

关于对tickets的数据处理是个难点,深度优先搜索(dfs)比较好理解

class Solution:
    def findItinerary(self, tickets: List[List[str]]) -> List[str]:
        self.adj = {}
        tickets.sort(key = lambda x:x[1])
        for u, v in tickets:
            if u in self.adj:self.adj[u].append(v)
            else: self.adj[u] = [v]
        self.result = []
        self.dfs("JFK")
        return self.result[::-1]
    def dfs(self, s):
        while s in self.adj and len(self.adj[s]) > 0:
            v = self.adj[s][0]
            self.adj[s].pop(0)
            self.dfs(v)
        self.result.append(s)

leetcode 51 N皇后

难点:棋盘的构建,判断是否满足条件

class Solution:
    def solveNQueens(self, n: int) -> List[List[str]]:
        result = []
        chessboard = ['.' * n for _ in range(n)]
        self.backtracking(n, 0, chessboard, result)
        return result
    def backtracking(self, n, row, chessboard, result):
        if row == n:
            result.append(chessboard[:])
            return
        for col in range(n):
            if self.isValid(row, col, chessboard):
                chessboard[row] = chessboard[row][:col] + 'Q' + chessboard[row][col + 1:]
                self.backtracking(n, row + 1, chessboard, result)
                chessboard[row] = chessboard[row][:col] + '.' + chessboard[row][col + 1:]
    def isValid(self, row, col, chessboard):
        for i in range(row):
            if chessboard[i][col] == 'Q':
                return False
        i, j = row - 1, col - 1
        while i >= 0 and j >= 0:
            if chessboard[i][j] == 'Q':
                return False
            i -= 1
            j -= 1
        i, j = row - 1, col + 1
        while i >= 0 and j < len(chessboard):
            if chessboard[i][j] == 'Q':
                return False
            i -= 1
            j += 1
        return True

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值