[LeetCode]Scramble String

class Solution {
//recursive solution is straight forward, just think about a binary tree, we should check
//if those sub trees are same(1. left==right, right==left or 2. left==left, right==right)

//observe the recursive solution we can find that there are some duplicated calculations,
//So we can use DP to save these calculated problems
//transform equation:
//define f[i][j][k] as: if s1(i, i+k-1) and s2(j, j+k-1) are scramble
//then f[j][j][k]|=f[i][j][subLen]&&f[i+subLen][j+subLen][k-subLen]
//f[i][j][k]|=f[i][k-subLen+j][subLen]&&f[i+subLen][j][k-subLen]
public:
	bool isScramble(string s1, string s2) {
		// Start typing your C/C++ solution below
		// DO NOT write int main() function
		//return Recursive(s1, s2);
		return DP(s1, s2);
	}

	bool Recursive( string s1, string s2 ) 
	{
		//throw std::exception("The method or operation is not implemented.");
		if(s1.size() != s2.size()) return false;
		vector<int> cnt(256, 0);
		for(int i = 0; i < s1.size(); ++i)
			cnt[s1[i]]++;
		for(int i = 0; i < s2.size(); ++i)
			cnt[s2[i]]--;
		for(int i = 0; i < cnt.size(); ++i)
			if(cnt[i] != 0) return false;
		int n = s1.size();
		if(n == 1) return true;
		//partition
		for (int i = 1; i < n; ++i)//i is the size of one sub tree
		{
			if( Recursive( s1.substr(0, i), s2.substr(0, i) ) && Recursive( s1.substr(i, n-i), s2.substr(i, n-i) )
				|| Recursive( s1.substr(0, i), s2.substr(n-i, i) ) && Recursive( s1.substr(i, n-i), s2.substr(0, n-i) ) )
				return true;
		}
		return false;
	}

	bool DP(string s1, string s2)
	{
		if(s1.size() != s2.size()) return false;
		int n = s1.size();
		vector<vector<vector<bool>>> f(n, vector<vector<bool>>(n, vector<bool>(n+1, false) ) );
		for (int i = 0; i < n; ++i)
		{
			for (int j = 0; j < n; ++j)
			{
				f[i][j][1] = s1[i]==s2[j];
			}
		}
		for (int k = 2; k <= n; ++k)
		{
			for (int i = 0; i+k-1 < n; ++i)
			{
				for (int j = 0; j+k-1 < n; ++j)
				{
					for (int subLen = 1; subLen < k; ++subLen)
					{
						if(f[i][j][subLen]&&f[i+subLen][j+subLen][k-subLen]
							|| f[i][k-subLen+j][subLen]&&f[i+subLen][j][k-subLen])
							{
								f[i][j][k] = true;
								break;
							}
					}
				}
			}
		}//end of dp
		return f[0][0][n];
	}
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI记忆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值