[刷题] dfs回溯 合集

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/programmingfool5/article/details/82784830

DFS 一般的套路模板:

def dfs(当前状态,成员变量,全局变量)

	     if(当前状态为边界状态):
	        记录或输出
	        return
	     for i in range(横向遍历解答树所有子节点):
	        #扩展出一个子状态。
	        if(不满足条件):
	           	continue or break
	        #  恢复全局变量    #回溯部分
	        if(子状态满足约束条件):
	              dfs(子状态)  #修改了全局变量
	          

题目: Permutations

Input:
[1,2,3]

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

def Permutations (nums):
	ans = []
	dfs(nums,[],ans)
	return ans
	
def dfs(nums, tmp, ans):
	if not nums:
		#if tmp not in ans:当数组中有相同的元素时
			ans.append(tmp)
			return 
	for i in range(len(nums)):
		dfs(nums[:i]+nums[i+1:], tmp+[nums[i]], ans)⭐️

题目:

Given two integers n and k, return all possible combinations of k numbers out of 1 … n. 返回k个数的组合.

Example:

Input: n = 4, k = 2
Output:
[[2,4], [3,4],[2,3], [1,2], [1,3], [1,4]]


class Solution(object):
    def combine(self, n, k):
        ans=[]
        self.dfs(n,1,k,[],ans)
        return ans
        
    def dfs(self,n,start,k,ret,ans):
      if k <= 0 :
          ans.append(ret)
      else:
        for i in range(start,n+1):
            self.dfs(n,i+1,k-1,ret+[i],ans)
            

题目:

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

#1
def subset_recursive(nums):
    ans = []
    dfs(nums, 0, [], ans)
    return ans


def dfs1(nums, start, ret, ans):
    ans.append(ret)
    for i in range(start, len(nums)):
        dfs(nums, i + 1, ret + [nums[i]], ans)
   
 #2 位图
 class Solution(object):
    def subset1(self, nums):
        nums_ = pow(2,len(nums))
        ans= [ []for _ in range(nums_)]
        for i in range(len(nums)):
          for j in range(nums_):
            if (j>>i) & 1:
              ans[j].append(nums[i])
        return ans
       

带有重复元素的子集:

    def subsetsWithDup(self, nums):
        res = []
        nums.sort()  #!!! 先排序
        self.dfs(nums, 0, [], res)
        return res

    def dfs(self, nums, index, path, res):
        res.append(path)
        for i in range(index, len(nums)):
            if i > index and nums[i] == nums[i - 1]:⭐️
                continue
            self.dfs(nums, i + 1, path + [nums[i]], res)

题目:组合数的和

Input: candidates = [2,5,2,1,2], target = 5,
A solution set is:
[
[1,2,2],
[5]
]

class Solution:
  
    def combinationSum2(self, nums, target):
        ans = []
        nums.sort()
        print(nums[:])
        self.dfs(nums, target, 0, [], ans)
        return ret

    def dfs(self, nums, target, start, path, ans):
        if target == 0 :
            ans.append(path)
            return
        for i in range(start, len(nums)):
            if nums[i] > target:
                break
            if i > start and nums[i] == nums[i-1]:
                continue
            self.dfs( nums, target - nums[i], i + 1, path + [nums[i]], ans )
            

题目: N皇后问题

class Solution(object):
    def solveNQueens(self, n):
    
        res = []
        columnforRow = [n]*n
        self.dfs(n,0,columnforRow,res)
        return res

    def dfs(self, n, row, columnforRow,ret):
        #back
        if row == n:
            item = []
            for i in range(n):
                rowstr = ""
                for j in range(n):
                    if columnforRow[i] == j:
                        rowstr += 'Q'
                    else:
                        rowstr += '.'
                item.append(rowstr)
            ret.append(item)
            return
		
        for i in range(n):
            columnforRow[row] = i  ⭐️
            if self.check(row,columnforRow) :
                self.dfs(n,row + 1,columnforRow,ret) 子状态
        #track

    def check (self, row, columnforRow):
        for i in range(row):
            if(columnforRow[row] == columnforRow[i] or abs(columnforRow[row]-columnforRow[i]) == row - i):
                return False
        return True

题目:

地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?

思路: 与八皇后的思路基本一致, 根据模板就可以

def moveCounts(threshold, rows, cols):
	if threshold < 0 or rows<=0 or cols <= 0:
		return 0
	visited  = [[ False for _ in range(cols)] for _ in range(rows)]
	counts = self.dfs(threshold, rows, cols, 0, 0, visited)
	return counts
	
def dfs(threshold, rows, cols, i, j, visited):
	counts = 0
	if self.check(threshold, rows, cols, i, j, visited):⭐️ 判定条件
		visited[i][j] = True ⭐️子状态
		counts = 1 + self.dfs(threshold, rows, cols, i+1, j, visited)\ 
						+self.dfs(threshold, rows, cols, i-1, j, visited)\
						+self.dfs(threshold, rows, cols, i, j+1, visited)\
						+self.dfs(threshold, rows, cols, i, j-1, visited)
	 return counts
	 
def check(threshold, rows, cols, i, j, visited):
	if 0<= i < rows and 0<= j < cols and not visited[i][j] and self.getsum(i)+self.getsum(j)<= threshold:
		return True
	return False
	
def getsum(number):
	sum_ = 0
	while number > 1:
		sum_ += number % 10
		number //= 10
	return sum _
	

猜你喜欢

转载自blog.csdn.net/programmingfool5/article/details/82784830
今日推荐