力扣131-分割字符串

第八十一天 --- 力扣131-分割字符串

题目一

力扣:131

在这里插入图片描述

思路

1、要先弄懂本题目是啥意思,要对s进行分割,分割出来的各个部分必须要是回文的,要求出所有可能的组合,这个一听,求出所有可能的情况,这个时候就要想到,可能是回溯算法,也有可能是DP,再看,是字符串分割问题,这种问题一般就是定位到回溯法暴力枚举所有可能的结果,用一些条件进行剪枝来优化。
2、到了这里我们来分析一下什么时候用回溯:
组合问题:N个数里面按一定规则找出k个数的集合
排列问题:N个数按一定规则全排列,有几种排列方式
切割问题:一个字符串按一定规则有几种切割方式
子集问题:一个N个数的集合里有多少符合条件的子集
棋盘问题:N皇后,解数独等等
3、回溯问题通用的一个模板:

void backtracking(参数) {
    
    
    if (终止条件) {
    
    
        存放结果;
        return;
    }

    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
    
    
        处理节点;
        backtracking(路径,选择列表); // 递归
        回溯,撤销处理结果
    }
}

4、综上,本体可以确定了,用回溯算法,回溯算法,最简单,最有效,最清晰的分析方法就是,画一棵树来分析:
在这里插入图片描述
所以当分析到了某个点i的时候,就要枚举从他开始的后面所有点,因为每一处都可能是分割点,如果能分割就递归走下去,分割条件就是是回文串,这也同样起到了剪枝的效果。
5、因为每一次都要回文串判断,所以我们想能不能在最短时间内判断是不是回文串,可以,用unordered_set,那前提得把所有可能的回文串存进去,所以我们要预处理,存进去所有回文串,用DP,这个就略过了,介绍过很多遍了。

代码

注意:
1、这里用的是全局量维护某一个答案,所以在回溯回来之后,说明刚才哪个分支已经完事了,所以要pop_back出去

class Solution {
    
    
public:
	vector<vector<string>> ans;//答案
	vector<string> tmp;//临时

	bool dp[100][100] = {
    
    };//DP
	unordered_set<string> item;//hash,快速判断回文串

	int n = 0;
	string s;

	void getArrange(int i) {
    
    //回溯法
		if (i == n) {
    
    //走到尽头,说明此分割有效
			ans.push_back(tmp);
			return;
		}
		for (int j = i; j < n; j++) {
    
    //枚举身后的,要从i开始,包括自己本身
			if (item.count(s.substr(i, j - i + 1))) {
    
    
				tmp.push_back(s.substr(i, j - i + 1));//加入临时答案
				getArrange(j + 1);//说明此次i-j合法,从j处分割,之后的进入递归
				tmp.pop_back();//分支完事,弹出,恢复现场
			}
		}
	}

	vector<vector<string>> partition(string s) {
    
    
		n = s.size();
		this->s = s;
		for (int i = 0; i < n; i++) {
    
    //DP预处理,初始化
			dp[i][i] = true;
			item.insert(s.substr(i, 1));
		}
		for (int i = 0; i < n - 1; i++) {
    
    //初始化
			if (s[i] == s[i + 1]) {
    
    
				dp[i][i + 1] = true;
				item.insert(s.substr(i, 2));
			}
		}
		for (int l = 2; l < n; l++) {
    
    
			for (int i = 0, j; i + l < n; i++) {
    
    
				j = i + l;
				if (s[i] == s[j] && dp[i + 1][j - 1]) {
    
    
					dp[i][j] = true;
					item.insert(s.substr(i, l + 1));
				}
			}
		}
		getArrange(0);
		return ans;
	}
};

(所有代码均已在力扣上运行无误)

经测试,该代码运行情况是(经过多次测试所得最短时间):

在这里插入图片描述

在这里插入图片描述

おすすめ

転載: blog.csdn.net/qq_45678698/article/details/120728556