算法学习(九)

学习内容:

优先搜索算法:包括深度优先搜索和广度优先搜索;深度优先搜索(DFS):在搜索到一个新节点时,立即对该新节点进行遍历;因此遍历需要用先入后出的栈来实现,也可以通过与栈等价的递归来实现;广度优先搜索(BFS):一层层进行遍历,需要用先入先出的队列进行遍历。

学习产出:

回溯法:优先搜索特殊情况,常用于需要记录状态的深度优先搜索。步骤有修改当前节点状态—递归子节点—回改当前节点状态;
1.按引用传状态
2.所有状态修改在递归后完成
回溯法修改一般有两种情况:一是修改最后一位;二是修改访问标记

回溯法

LeetCode 46 全排列

给定一个 没有重复 数字的序列,返回其所有可能的全排列。

示例:

输入: [1,2,3]
输出:
[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/permutations
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。      
    

题解

采用回溯算法,对于每一个当前位置i,将其与之后的任意位置进行交换,然后继续处理i+1的位置,知道处理到最后一位,利用回溯算法,只对源数组进行修改,在递归完后再修改回来

代码(python)

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        ans = []
        def backtracking(nums,level): #回溯
            if level == len(nums)-1:
                ans.append(nums[:]) #后续的操作会对nums产生影响,使用nums[:]相当于取nums对应对象的一个视图,后续的操作不会产生影响
                return
            for i in range(level,len(nums)):
                nums[i],nums[level] = nums[level],nums[i]  #修改当前节点状态
                backtracking(nums,level+1) #递归子节点
                nums[i], nums[level] = nums[level], nums[i] #修改回当前节点状态
        backtracking(nums , 0)
        return ans
    			

注:第一次发现nums值会被后续操作修改,nums[:]相当于对nums拷贝,与nums地址不同

LeetCode 77 组合

给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。

示例:

输入: n = 4, k = 2
输出:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/combinations
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。      
    

题解

上一题排列回溯,用的是交换位置,这题组合回溯,用的是把当前的数字加入结果中

代码(python)

class Solution:
    def combine(self, n: int, k: int) -> List[List[int]]:
        ans = []
        com = [None] * k #初始化
        count = 0 #位置标记
        def backtracking(com,count,pos): #回溯
            if count == k:
                ans.append(com[:]) 
                return
            for i in range(pos,n+1):
                com[count] = i    #修改当前节点状态
                count += 1    #修改当前节点位置标记
                backtracking(com,count,i+1) #递归子节点
                count -= 1	#修改回当前节点
        backtracking(com,count,1)
        return ans

当然回溯在python有内置函数 itertools库内置了这个函数可以直接调用
所以以上两题均可直接调用函数


class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        """LeetCode 46 全排列 itertools库内置了这个函数"""
        return itertools.permutations(nums)


###########################################################


class Solution:
    def combine(self, n: int, k: int) -> List[List[int]]:
    	"""LeetCode 77 组合 itertools库内置了这个函数"""
         return list(itertools.combinations(range(1,n+1),k))


##########################################################


		def backtracking(状态, 条件列表):
			"""回溯通用参考模板"""
    		if 满足结束条件:
        		结果.append(状态)
        		return
    		for 条件 in 条件列表:    # 核心代码段
       			修改当前节点状态
        		递归子节点执行backtracking()
        		修改回当前节点



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值