[Coding Made Simple] String Interleaving

Given three strings, return true if third string is interleaving of first and second string.

By running some examples, it seems that as long as s1.length() + s2.length() == s3.length() and both s1 and s2 are common subsequences of s3,

s3 is interleaving of s1 and s2. However, this assumption is not correct as shown in the following counter example.

s1 = "aba", s2 = "aca", s3 = "abacaa", both s1 and s2 are common subsequence of s3, but s3 is not interleaving of s1 and s2. The problem lies in

that s1 and s2 have overlapping characters in the common subsequence portion of s3.

Solution 1. Recursion

Because we need to keep the relative order of characters of s1 and s2 in s3, we know that for the last character of s3 must be either from s1‘s or s2‘s

end if s3 is interleaving of s1 and s2. If this is not the case, we know for sure s3 is not interleaving of s1 and s2.

Based on the above observation, the following recursive formulas are derived.

Base case: all characters in s3 are checked already, return true.

For s1[0.....i], s2[0....j], s3[0... i + j + 1],

case 1: there are unused characters in s1, i >= 0 && s1[i] == s3[i + j + 1]

       check if s3[0....i + j] is interleaving of s1[0...i - 1] and s2[0....j];

if case 1 is false, proceed to case 2.

case 2: there are unused characters in s2, j >= 0 && s2[j] == s3[i + j + 1]

       check if s3[0....i + j] is interleaving of s1[0...i] and s2[0....j - 1];

if case 2 is false, we‘ just checked all possibilities, so return false.

Similarly with a lot of recursive solutions, this solution has the overlapping subproblems issue.

For example,  for s1[0, 6] and s2[0, 5], we have the following recursive tree.

                            s1[0,6] and s2[0,5]

              s1[0,5] and s2[0,5]                    s1[0, 6] and s2[0,4]

    s1[0,4] and s2[0, 5]      s1[0,5] and s2[0,4]           s1[0,5] and s2[0,4]      s1[0,6] and s2[0,4]

The red subproblems are overlapped.

 1 public class InterleavingString {
 2     public boolean isInterleavingStringRecursion(String s1, String s2, String s3) {
 3         if(s1.length() + s2.length() != s3.length()) {
 4             return false;
 5         }
 6         return recursiveHelper(s1, s1.length() - 1, s2, s2.length() - 1, s3, s3.length() - 1);
 7     }
 8     private boolean recursiveHelper(String s1, int endIdx1, String s2, int endIdx2, String s3, int endIdx3) {
 9         if(endIdx3 < 0) {
10             return true;
11         }
12         if(endIdx1 >= 0 && s1.charAt(endIdx1) == s3.charAt(endIdx3)) {
13             if(recursiveHelper(s1, endIdx1 - 1, s2, endIdx2, s3, endIdx3 - 1)) {
14                 return true;
15             }
16         }
17         else if(endIdx2 >= 0 && s2.charAt(endIdx2) == s3.charAt(endIdx3)) {
18             if(recursiveHelper(s1, endIdx1, s2, endIdx2 - 1, s3, endIdx3 - 1)) {
19                 return true;
20             }
21         }
22         return false;
23     }
24     public static void main(String[] args) {
25         String s1 = "aab", s2 = "axy", s3 = "aaxaby", s4 = "abaaxy";
26         String s5 = "aabcc", s6 = "dbbca", s7 = "aadbbcbcac", s8 = "aadbbbaccc";
27         InterleavingString test = new InterleavingString();
28         System.out.println(test.isInterleavingStringRecursion(s1, s2, s3));
29         System.out.println(test.isInterleavingStringRecursion(s1, s2, s4));
30         System.out.println(test.isInterleavingStringRecursion(s5, s6, s7));
31         System.out.println(test.isInterleavingStringRecursion(s5, s6, s8));
32     }
33 }

Solution 2. Dynamic Programming

State: T[i][j]: whether s3[0 ~ i + j - 1] is interleaving of s1[0 ~ i - 1] and s2[0 ~ j - 1]

Function: same with the recursive solution.

Init: T[0][0] = true, as an empty string is interleaving of two empty strings 

 1 public boolean isInterleavingStringDp(String s1, String s2, String s3) {
 2     if(s1.length() + s2.length() != s3.length()) {
 3         return false;
 4     }
 5     boolean[][] T = new boolean[s1.length() + 1][s2.length() + 1];
 6     T[0][0] = true;
 7     for(int i = 1; i < T.length; i++) {
 8         T[i][0] = s1.charAt(i - 1) == s3.charAt(i - 1) && T[i - 1][0];
 9     }
10     for(int j = 1; j < T[0].length; j++) {
11         T[0][j] = s2.charAt(j - 1) == s3.charAt(j - 1) && T[0][j - 1];
12     }
13     for(int i = 1; i < T.length; i++) {
14         for(int j = 1; j < T[0].length; j++) {
15             if(s1.charAt(i - 1) == s3.charAt(i + j - 1) && T[i - 1][j]) {
16                 T[i][j] = true;
17             }
18             else if(s2.charAt(j - 1) == s3.charAt(i + j - 1) && T[i][j - 1]) {
19                 T[i][j] = true;
20             }
21             else {
22                 T[i][j] = false;
23             }
24         }
25     }
26     return T[s1.length()][s2.length()];
27 }

Related Problems

Distinct Subsequence

时间: 2024-08-23 22:34:48

[Coding Made Simple] String Interleaving的相关文章

[Coding Made Simple] Box Stacking

Given boxes of different dimensions, stack them on top of each other to get maximum height such that box on top has strictly less length and width than box under it. Algorithm. 1. get all the box permutation with each permutation's length >= width; s

csu 1550: Simple String (字符串)

1550: Simple String Time Limit: 1 Sec  Memory Limit: 256 MB Submit: 249  Solved: 112 [Submit][Status][Web Board] Description Welcome,this is the 2015 3th Multiple Universities Programming Contest ,Changsha ,Hunan Province. In order to let you feel fu

Water --- CSU 1550: Simple String

Simple String Problem's Link:   http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1550 Mean: 略. analyse: 水题. Time complexity: O(n) Source code:  // Memory Time // 1347K 0MS // by : crazyacking // 2015-03-29-12.08 #include<map> #include<queue> #

[Coding Made Simple] Maximum Subsquare surrounded by &#39;X&#39;

Given a 2D matrix where every element is either 'O' or 'X', find the largest subsquare surrounded by 'X'. Examples: Input: mat[N][N] = { {'X', 'O', 'X', 'X', 'X'}, {'X', 'X', 'X', 'X', 'X'}, {'X', 'X', 'O', 'X', 'O'}, {'X', 'X', 'X', 'X', 'X'}, {'X',

(比赛)A - Simple String Problem

A - Simple String Problem Time Limit:10000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Practice POJ 2236 Description An earthquake takes place in Southeast Asia. The ACM (Asia Cooperated Medical team) have set up a wireless network wit

[Coding Made Simple] Matrix Chain Multiplication

Given some matrices, in what order you would multiply them to minimize cost of multiplication. The following problem formulation is extracted from this link. Problem Formulation Note that although we can use any legal parenthesization, which will lea

[Coding Made Simple] Optimal Strategy Game Pick from Ends of array

N pots, each with some number of gold coins, are arranged in a line. You are playing a game against another player. You take turns picking a pot of gold. You may pick a pot from either end of the line, remove the pot, and keep the gold pieces. The pl

[Coding Made Simple] Burst Balloon

Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented by array nums. You are asked to burst all the balloons. If the you burst balloon i you will get nums[left] * nums[i] * nums[right] coins. Here left and r

D - Simple String CSU - 1550

http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1550 很久都没补这题,最近想学网络流,就看看,队友以前用网络流过的,Orz, 但是这题只需要简单的判断,可能想起来有点麻烦. 考虑一定要从A串取出n个,B串也一定要取出n个,那么A和C的交集一定要大于等于n,同理B. 同时为了得到C串,还需要A + B和C的交集一定要大于等于n * 2 怎么说呢.可以画个图表示下,反正找不到反例.就先码一波. #include <cstdio> #incl