回溯算法-深度优先搜索

来源于leetcode一道中等难度的题,匹配括号。

回溯法-深度优先搜索

回溯法思路的简单描述是:把问题的解空间转化成了图或者树的结构表示,然后使用深度优先搜索策略进行遍历,遍历的过程中记录和寻找所有可行解或者最优解。

回溯法按深度优先策略搜索问题的解空间树。首先从根节点出发搜索解空间树,当算法搜索至解空间树的某一节点时,先利用剪枝函数判断该节点是否可行(即能得到问题的解)。如果不可行,则跳过对该节点为根的子树的搜索,逐层向其祖先节点回溯;否则,进入该子树,继续按深度优先策略搜索。

        回溯法的基本行为是搜索,搜索过程使用剪枝函数来为了避免无效的搜索

        剪枝函数包括两类:1. 使用约束函数,剪去不满足约束条件的路径;

                                   2.使用限界函数,剪去不能得到最优解的路径。

                                  (在搜索过程中剪掉已经出现不符合条件的路径,避免继续向下展开)

        问题的关键在于如何定义问题的解空间,转化成树(即解空间树)。解空间树分为两种:子集树和排列树。两种在算法结构和思路上大体相同。

       当问题是要求满足某种性质(约束条件)的所有解或最优解时,往往使用回溯法。

LeetCode题解代码

public List generateParenthesis(int n) {
		List list = new ArrayList<>();
		if (n == 0){
			return list;
		}
		dfs("",n,n,list);
		return list;
	}

	public void dfs(String res ,int left,int right,List temp){
    	//判断是否已经达到了叶子结点,也就是最终解
    	if (left == 0 && right == 0){
    		temp.add(res);
    		return;
		}
    	//剪枝
		//当遍历过程中发现已经有了不符合条件的情况产生,剪去这条路径,减少不必要的搜索过程
    	if (right < left){
    		return;
		}

    	//树的两个节点,也就是两个不同的路径,向下遍历
		//采用递归的形式,将两种情况分解为树的两个节点,向下遍历
		//这里递归进去之后,会在这个结点为根的情况下再次产生两个结点,直到遍历到最后的叶子结点
    	if (left > 0){
    		dfs(res + "(",left - 1,right,temp);
		}
    	if (right > 0){
    		dfs(res + ")",left,right - 1,temp);
		}
	}

 

image.png

posted @ 2021-12-15 15:44  YanSss  阅读(330)  评论(1编辑  收藏  举报