现在的位置: 首页 > 综合 > 正文

[leetcode] Interleaving String

2018年05月13日 ⁄ 综合 ⁄ 共 1825字 ⁄ 字号 评论关闭

Given three strings: s1, s2, s3, determine whether s3 is formed by the interleaving of s1 and s2.

Example

For s1 = "aabcc" s2 = "dbbca"

    - When s3 = "aadbbcbcac", return true.

    - When s3 = "aadbbbaccc", return false.

Challenge

O(n^2) time or better

解题思路:

s3的第一个字符分别和s1,s2的第一个字符做比较,如果其中一个相同,则去除s3和具有相同前缀的字符串的第一个字符。继续下一轮的比较。最发麻的问题出现了,如果s1和s2的前缀相同,那么选择那个字符串继续比较呢?

这是一个典型的动态规划的问题。借鉴网上分析思路:

dimension dp:

这是一个二维的动态规划,

s1 = "aabcc"
s2 = "dbbca"
s3 = "aadbbcbcac"

函数

bool isInterleaving(string &s1, int len1, string &s2, int len2, string &s3, int len3);

表示子问题:si取前leni个字符的话,那么实际上可以得到这样的一个公式:

isInterleaving(s1,len1,s2,len2,s3,len3) 
    =   (s3.lastChar == s1.lastChar) && isInterleaving(s1,len1 - 1,s2,len2,s3,len3 - 1)
      ||(s3.lastChar == s2.lastChar) && isInterleaving(s1,len1,s2,len2 - 1,s3,len3 - 1)

由于len3 === len1 + len2,所以这个问题里面实际上存在着两个变量,是一个二维动态规划题目。

从矩阵的角度来看的话,每一个元素的值,依赖于它的上边和左边两个值。

测试集运行时间,解法一3391ms,解法二:2781 ms,动态规划还是比较好的解法。

解法一: 传统迭代实现

public boolean isInterleave(String s1, String s2, String s3) {
		if ((s1.length() + s2.length()) != s3.length())
			return false;

		if (s3.length() == 0)
			return true;
		else {
			char c = s3.charAt(0);
			boolean f = false;
			if (s1.length() > 0 && s1.charAt(0) == c) {
				f = isInterleave(s1.substring(1), s2, s3.substring(1));
			}
			if (!f && s2.length() > 0 && s2.charAt(0) == c) {
				f = isInterleave(s1, s2.substring(1), s3.substring(1));
			}
			return f;
		}
	}

解法二: 动态规划

public class Solution {
    /**
     * Determine whether s3 is formed by interleaving of s1 and s2.
     * @param s1, s2, s3: As description.
     * @return: true or false.
     */
    public boolean isInterleave(String s1, String s2, String s3) {
		boolean[][] dp = new boolean[s1.length() + 1][s2.length() + 1];
		if ((s1.length() + s2.length()) != s3.length())
			return false;

		for (int i = 0; i < dp.length; i++)
			for (int j = 0; j < dp[i].length; j++)
				dp[i][j] = false;
		dp[0][0] = true;
		for (int i = 0; i <= s1.length(); i++) {
			for (int j = 0; j <= s2.length(); j++) {
				if (dp[i][j]) {
					if (i != s1.length() && s1.charAt(i) == s3.charAt(i + j))
						dp[i + 1][j] = true;
					if (j != s2.length() && s2.charAt(j) == s3.charAt(i + j))
						dp[i][j + 1] = true;
				}
			}
		}

		return dp[s1.length()][s2.length()];
	}
	
}

【上篇】
【下篇】

抱歉!评论已关闭.