[leetcode]中级算法——回溯算法

本文详细介绍了如何使用回溯算法解决LeetCode中的经典问题,包括电话号码的字母组合、括号生成、全排列、子集和单词搜索。每个问题都附带了作者自己编写的代码示例,展示了如何通过递归实现回溯法来找到所有可能的解决方案。
摘要由CSDN通过智能技术生成

电话号码的字母组合

Given a string containing digits from 2-9 inclusive, return all possible letter combinations that the number could represent.

A mapping of digit to letters (just like on the telephone buttons) is given below. Note that 1 does not map to any letters.

Example:

Input: "23"
Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

Code(By myself):

class Solution(object):
    def letterCombinations(self, digits):
        """
        :type digits: str
        :rtype: List[str]
        """
        dic = {
            '2' : 'abc',
            '3' : 'def',
            '4' : 'ghi',
            '5' : 'jkl',
            '6' : 'mno',
            '7' : 'pqrs',
            '8' : 'tuv',
            '9' : 'wxyz'
        }
        result = []
        for each in digits:
            temp = []
            if result == []:
                result = list(dic[each])
            else:
                for i in result:
                    for j in dic[each]:
                        temp.append(i+j)
                result = temp
        return result
Code(others):
class Solution(object):
    def letterCombinations(self, digits):
        """
        :type digits: str
        :rtype: List[str]
        """
        string_map = {
            '2':"abc",
            '3':"def",
            '4':"ghi",
            '5':"jkl",
            '6':"mno",
            '7':"pqrs",
            '8':"tuv",
            '9':"wxyz"
        }
        result = []
        def get(pos,now):
            if pos == len(digits) :
                if len(now) > 0:
                    result.append(now)
            else :
                for eve in string_map[digits[pos]]:
                    now += eve 
                    get(pos+1,now)
                    now = now[:-1]
        get(0,"")
        return result

括号的生成

Given  n  pairs of parentheses, write a function to generate all combinations of well-formed parentheses.

Example:

For example, given n = 3, a solution set is:

[
  "((()))",
  "(()())",
  "(())()",
  "()(())",
  "()()()"
]

Code(By myself):

class Solution(object):
    def generateParenthesis(self, n):
        """
        :type n: int
        :rtype: List[str]
        """
        result = []
        if n == 0:
            return result
        self.generate(n,n,'',result)
        return result
    
    def generate(self,left,right,str,result):
        if left == 0 and right == 0:
            result.append(str)
            return
        if left > 0:
            self.generate(left-1,right,str+'(',result)
        if right > 0 and left < right:
            self.generate(left,right-1,str+')',result)
总结:

此类问题可用递归解决

全排列

Given a collection of  distinct  integers, return all possible permutations.

Example:

Input: [1,2,3]
Output:
[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]

Code(By myself):

class Solution(object):
    def permute(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        result = []
        n = len(nums)
        if n == 0:
            return result
        if n == 1:
            return [nums]
        for each in nums:
            result.append([each])
        result = self.per(1,n,nums,result)
        return result
    
    def per(self,i,n,nums,result):
        temp = []
        for each in result:
            for num in nums:
                l = each[:]
                if num not in l:
                    l.append(num)
                    temp.append(l)
        result = temp
        if i+1 == n:
            return result
        result = self.per(i+1,n,nums,result)
        return result
Code(others):
import itertools
class Solution(object):
    def permute(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        return [i for i in itertools.permutations(nums)]
class Solution(object):
    def permute(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        if len(nums)==1:
            return [nums]
        results = []
        result = self.permute(nums[1:])
        for i in range(len(nums)):
            for j in range(len(result)):
                tmp = result[j][:]
                tmp.insert(i, nums[0])
                results.append(tmp)
        return results
总结:

itertools.permutations()返回p中任意取r个元素做排列的元组的迭代器

子集

Given a set of distinct integers, nums, return all possible subsets (the power set).

Note: The solution set must not contain duplicate subsets.

Example:

Input: nums = [1,2,3]
Output:
[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]

Code(By myself):

import itertools
class Solution(object):
    def subsets(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        # result = []
        # n = len(nums)
        # while n+1:
        #     result += [i for i in itertools.combinations(nums,n)]
        #     n -= 1
        # return result
        res = [[]]  
        for num in nums :  
            for temp in res[:] :  
                x = temp[:]  
                x.append(num)  
                res.append(x)  
        return res 
Code(others):
class Solution(object):
    def subsets(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        res = list()
        def dfs(lst, cur):
            if cur == -1:
                res.append(lst)
                return
            dfs(lst, cur-1)
            dfs(lst+[nums[cur]], cur-1)
            
        dfs([], len(nums)-1)
        return res

单词搜索

Given a 2D board and a word, find if the word exists in the grid.

The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.

Example:

board =
[
  ['A','B','C','E'],
  ['S','F','C','S'],
  ['A','D','E','E']
]

Given word = "ABCCED", return true.
Given word = "SEE", return true.
Given word = "ABCB", return false.

Code(By myself):

class Solution(object):
    def exist(self, board, word):
        """
        :type board: List[List[str]]
        :type word: str
        :rtype: bool
        """
        if not word:
            return True
        if len(word) > len(board) * len(board[0]):
            return False
        self.m = len(board)
        self.n = len(board[0])
        for i in range(self.m):
            for j in range(self.n):
                path = []
                if board[i][j] == word[0]:
                    path.append((i,j))
                    if self.nextExist(i,j,path,board,word[1:]):
                        return True
        return False
    
    def nextExist(self,i,j,path,board,word):
        if not word:
            return True
        stack = []
        if i > 0 and board[i-1][j] == word[0] and (i-1,j) not in path:
            stack.append((i-1,j))
        if j > 0 and board[i][j-1] == word[0] and (i,j-1) not in path:
            stack.append((i,j-1))
        if i < self.m-1 and board[i+1][j] == word[0] and (i+1,j) not in path:
            stack.append((i+1,j))
        if j < self.n-1 and board[i][j+1] == word[0] and (i,j+1) not in path:
            stack.append((i,j+1))
        while stack:
            a,b = stack.pop()
            path.append((a,b))
            if self.nextExist(a,b,path,board,word[1:]):
                return True
        path.pop()
        return False
Code(others):
import collections
class Solution(object):
    def exist(self, board, word):
        """
        :type board: List[List[str]]
        :type word: str
        :rtype: bool
        """
        def precheck(board,word):
            cb=collections.defaultdict(int)
            cw=collections.defaultdict(int)
            for i in range(m):
                for j in range(n):
                    cb[board[i][j]]+=1
            for c in word:
                cw[c]+=1
            for c in cw:
                if (c not in cb) or cw[c]>cb[c]:
                    return False
            return True
        def dfs(x,y,p):
            val=board[x][y]
            if val!=word[p]:
                return False
            if p==len(word)-1:
                return True
            board[x][y]='#'
            for dx,dy in zip([1,0,-1,0],[0,1,0,-1]):
                nx,ny=x+dx,y+dy
                if 0<=nx and nx<m and 0<=ny and ny<n:
                    if dfs(nx,ny,p+1):
                        return True
            board[x][y]=val
            return False
        
        
        m,n=len(board),len(board[0])
        if m==0:
            return False
        if not precheck(board,word):
            return False
        for i in range(m):
            for j in range(n):
                if dfs(i,j,0):
                    return True
        return False
总结:

可以加一个判断矩阵,递归进去时修改其值,在递归返回的时候恢复。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值