LeetCode Interleaving String

本文探讨了一个经典的编程面试题目——交错字符串问题。通过递归和动态规划两种方法详细解析了如何判断一个字符串是否可以通过两个给定字符串交错组成。文章对比了递归与动态规划的优缺点,并分享了代码实现细节。

好题呀,适合面试。理解题意后首先想到的是递归,画了画,写了写,确实可以递归,再想想,恩,也可以用DP,于是写了dp的程序提交第一次,失败,开辟的空间太小了,在开辟大一点却被编译器限制了;试试递归吧,果然时间限制;恩,肯定还有可以优化的地方,再仔细看看,确实如此,DP【i】【j】【k】中,k始终等于i+j,不是多此一举吗,试试确实能去掉k,因此也就去了一维,二维数组就可以开辟500*500的空间了,而三维数组最多开辟100*100*100的空间,AC~\(≧▽≦)/~啦啦啦。三种方法全部代码贴上:

// LeetCode_InterleavingString.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;

bool isInterleave02(string s1, string s2, string s3) {
	int lens1 = s1.length();
	int lens2 = s2.length();
	int lens3 = s3.length();
	if(lens1+lens2!=lens3)
		return false;
	bool dp[100][100][100];//more than 100*100*100 runtime error
	dp[0][0][0]=true;
	for (int k=1;k<=lens3;k++)
	{
		for (int i=0;i<=lens1;i++)
		{
			for (int j=0;j<=lens2;j++)
			{
				if(i+j==k)
				{
					if ((i>0&&s1[i-1]==s3[k-1]&&dp[i-1][j][k-1])||(j>0&&s2[j-1]==s3[k-1]&&dp[i][j-1][k-1]))
						dp[i][j][k] = true;
					else
						dp[i][j][k] = false;
				}
				else
					dp[i][j][k] = false;
			}
		}
	}
	return dp[lens1][lens2][lens3];
}

bool isInterleave03(string s1, string s2, string s3) {
	int lens1 = s1.length();
	int lens2 = s2.length();
	int lens3 = s3.length();
	if(lens1+lens2!=lens3)
		return false;
	bool dp[500][500];//500*500 alone not crush
	dp[0][0]=true;
	for (int i=0;i<=lens1;i++)
	{
		for (int j=0;j<=lens2;j++)
		{
			if(i==0&&j==0)
				continue;
			if ((i>0&&s1[i-1]==s3[i+j-1]&&dp[i-1][j])||(j>0&&s2[j-1]==s3[i+j-1]&&dp[i][j-1]))
				dp[i][j] = true;
			else
				dp[i][j] = false;
		}
	}
	return dp[lens1][lens2];
}

bool isInterleaveRecursive(string &s1,int i1,string &s2,int i2,string &s3,int i3){
	if(i1==s1.length()&&i2==s2.length()&&i3==s3.length())
		return true;
	if(i1==s1.length())
	{
		return s2.substr(i2,s2.length()-i2)==s3.substr(i3,s3.length()-i3);
	}
	if(i2==s2.length())
	{
		return s1.substr(i1,s1.length()-i1)==s3.substr(i3,s3.length()-i3);
	}
	return ((s1[i1]==s3[i3])&&isInterleaveRecursive(s1,i1+1,s2,i2,s3,i3+1))||((s2[i2]==s3[i3])&&isInterleaveRecursive(s1,i1,s2,i2+1,s3,i3+1));
}
bool isInterleave(string s1, string s2, string s3) {
	int lens1 = s1.length();
	int lens2 = s2.length();
	int lens3 = s3.length();
	if(lens1+lens2!=lens3)
		return false;
	return isInterleaveRecursive(s1,0,s2,0,s3,0);
}
int _tmain(int argc, _TCHAR* argv[])
{
	string s1,s2,s3;
	while(cin>>s1&&cin>>s2&&cin>>s3)
	{
		//s1="";s2="";s3="";
		cout<<isInterleave03(s1,s2,s3)<<endl;
	}
	system("pause");
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值