Leetcode 131. Palindrome Partitioning

Given a string s, partition s such that every substring of the partition is a palindrome.

Return all possible palindrome partitioning of s.

Example:

Input: “aab”
Output:
[
[“aa”,“b”],
[“a”,“a”,“b”]
]

method 1 backtracking

patition s 可以看作从左往右,不断往s插入一个分隔符,使得s分为左右两个部分,当left为回文时,接着对right进行递归回溯,插入分隔符

map<string, bool> palindromeMap;

bool isPalindrome(string str){
	if (palindromeMap.count(str)) return palindromeMap[str];
	bool res = true;
	for (int i = 0, j = str.size()-1; i < j; i++, j--)
	{
		if (str[i] != str[j]){
			res = false;
			break;
		}
	}
	palindromeMap[str] = res;
	return res;
}

void helper(vector<vector<string>>& ans, string part, vector<string> tmp){
	if (part == ""){
		ans.push_back(tmp);
	}
	else{
		for (int i = 0; i < part.size(); i++)
		{
			string left = part.substr(0, i + 1);
			if (!isPalindrome(left)) continue;

			tmp.push_back(left);
			string right = part.substr(i + 1, part.size() - (i + 1));
			helper(ans, right, tmp);
			tmp.pop_back();
		}
	}
}

method 2 dynamic programming

在回溯过程中,回文串的判断可以引入动态规划
动态规划主要用在了判断字符串是否是回文串上,dp[i][j]代表字符串中从i到j(包括j)是否是回文串,这样判断dp[i][j]是否为回文串主要分为以下三个步骤:

  1. 如果是一个字符,自然是回文
  2. 如果是两个字符,判断第一个和第二个是否相等
  3. 如果是多个字符,那就判断第一个和最后一个是否相等以及中间部分是否相等
void helper2(vector<vector<string>>& ans, string s, vector<string> tmp, int start){
	if (start == s.size()){
		ans.push_back(tmp);
	}else{
		for (int i = start; i < s.size(); i++)
		{
			if (!dp[start][i]){
				if (start == i) dp[start][i] = true;
				else if (start == i - 1) dp[start][i] = (s[start] == s[i]);
				else dp[start][i] = dp[start + 1][i - 1] && s[start] == s[i];
			}


			if (dp[start][i]){
				string left = s.substr(start, i - start+ 1);
				tmp.push_back(left);
				helper2(ans, s, tmp, i + 1);
				tmp.pop_back();
			}
		}
	}
}

vector<vector<string>> partition(string s) {
	vector<vector<string>> ans;
	if (s.size() == 0) return ans;
	dp.resize(s.size(), vector<bool>(s.size(), false));
	vector<string> tmp;
	helper2(ans, s, tmp, 0);

	return ans;
}

summary

  1. 递归回溯可以看作是从左往右分割的过程,左边是最小符合要求的集合,不需要递归,然后对右边继续递归
  2. 回文串可以用动态规划进行判断
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值