LeetCode097 Interleaving String

详细见:leetcode.com/problems/interleaving-string


Java Solution: github

package leetcode;

/*
 * 	Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2.

	For example,
	Given:
	s1 = "aabcc",
	s2 = "dbbca",
	
	When s3 = "aadbbcbcac", return true.
	When s3 = "aadbbbaccc", return false.
 */

public class P097_InterleavingString {
	/*
	 * 	已有的测试数据都通过,提交TLE
	 */
	static class Solution {
		int count = 0;
	    public boolean isInterleave(String s1, String s2, String s3) {
	    	if (s3 == null) {
	    		return null == s2 && s1 == null;
	    	}
	    	if (s1 == null || s1.length() == 0) {
	    		return s3.equals(s2);
	    	} else if (s2 == null || s2.length() == 0) {
	    		return s3.equals(s1);
	    	}
	    	if (s1.length() + s2.length() != s3.length()) {
	    		return false;
	    	}
	    	boolean ans = solve(s1.toCharArray(), 0, s2.toCharArray(), 0, s3.toCharArray(), 0);
	        System.out.println(count);
	    	return ans;
	    }
		private boolean solve(char[] ch1, int i1, char[] ch2, int i2, char[] ch3, int i3) {
			count ++;
			if (i1 == ch1.length && i3 < ch3.length) {
				return solve(ch2, i2, ch3, i3);
			} else if (i2 == ch2.length && i3 < ch3.length) {
				return solve(ch1, i1, ch3, i3);
			} else if (i3 == ch3.length) {
				return i1 == ch1.length && i2 == ch2.length;
			}
			if (ch1[i1] == ch2[i2]) {
				if (ch1[i1] != ch3[i3]) {
					return false;
				} else {
					return solve(ch1, i1 + 1, ch2, i2, ch3, i3 + 1) ||
							solve(ch1, i1, ch2, i2 + 1, ch3, i3 + 1);
				}
			}
			if (ch1[i1] == ch3[i3]) {
				return solve(ch1, i1 + 1, ch2, i2, ch3, i3 + 1);
			}
			if (ch2[i2] == ch3[i3]) {
				return solve(ch1, i1, ch2, i2 + 1, ch3, i3 + 1);
			}
			return false;
		}
		private boolean solve(char[] ch1, int i1, char[] ch2, int i2) {
			int j1 = i1, j2 = i2;
			while (j1 < ch1.length && j2 < ch2.length) {
				if (ch1[j1 ++] != ch2[j2 ++]) {
					return false;
				}
			}
			return j1 == ch1.length && j2 == ch2.length;
		}
	}
	/*	
	 *	对于这类问题,肯定要尝试DP
	 *	12 ms
	 */
	static class Solution2 {
		public boolean isInterleave(String s1, String s2, String s3) {
			if (s3 == null) {
	    		return null == s2 && s1 == null;
	    	}
	    	if (s1 == null || s1.length() == 0) {
	    		return s3.equals(s2);
	    	} else if (s2 == null || s2.length() == 0) {
	    		return s3.equals(s1);
	    	}
	    	int m = s1.length(), n = s2.length();
	    	if (m + n != s3.length()) {
	    		return false;
	    	}
	    	boolean[][] path = new boolean[m + 1][n + 1];
	    	path[0][0] = true;
	    	for (int i = 1; i < m + 1; i ++) {
	    		path[i][0] = path[i - 1][0] & (s1.charAt(i - 1) == s3.charAt(i - 1));
	    	}
	    	for (int j = 1; j < n + 1; j ++) {
	    		path[0][j] = path[0][j - 1] & (s2.charAt(j - 1) == s3.charAt(j - 1));
	    	}
	    	for (int i = 1; i < m + 1; i ++) {
	    		for (int j = 1; j < n + 1; j ++) {
	    			path[i][j] = (path[i - 1][j] & (s1.charAt(i - 1) == s3.charAt(i + j - 1))) ||
	    					(path[i][j - 1] & (s2.charAt(j - 1) == s3.charAt(i + j - 1)));
	    		}
	    	}
	    	return path[m][n];
		}
	}
}


C Solution: github

/*
    url: leetcode.com/problems/interleaving-string
    recur: TLE
    dp/dp2: AC 3ms 42.86%
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define bool int

bool cmp_str(char* s1, int i1, int n1, char* s2, int i2, int n2) {
    if (n1-i1 != n2-i2) return 0;
    while (i1 < n1) {
        if (s1[i1] != s2[i2]) return 0;
        i1 ++;
        i2 ++;
    }
    return 1;
}

bool search(char* s1, int i1, int n1, char* s2, int i2, int n2, char* s3, int i3, int n3) {
    if (i1 == n1) return cmp_str(s2, i2, n2, s3, i3, n3);
    if (i2 == n2) return cmp_str(s1, i1, n1, s3, i3, n3);
    if (s1[i1] == s3[i3] && search(s1, i1+1, n1, s2, i2, n2, s3, i3+1, n3))
        return 1;
    if (s2[i2] == s3[i3] && search(s1, i1, n1, s2, i2+1, n2, s3, i3+1, n3))
        return 1;
    return 0;
}

bool isInterleave_recur(char* s1, char* s2, char* s3) {
    int n1 = s1 == NULL ? 0 : strlen(s1);
    int n2 = s2 == NULL ? 0 : strlen(s2);
    int n3 = s3 == NULL ? 0 : strlen(s3);
    if (n1+n2 != n3) return 0;
    return search(s1, 0, n1, s2, 0, n2, s3, 0, n3);
}

bool isInterleave_dp(char* s1, char* s2, char* s3) {
    int n1 = s1 == NULL ? 0 : strlen(s1);
    int n2 = s2 == NULL ? 0 : strlen(s2);
    int n3 = s3 == NULL ? 0 : strlen(s3);
    int i1 = 0, i2 = 0, ans = 0;
    char** m = NULL;
    if (n1+n2 != n3) return 0;
    m = (char**) malloc(sizeof(char*) * (n1+1));
    for (i1 = 0; i1 <= n1; i1 ++) {
        m[i1] = (char*) malloc(sizeof(char) * (n2 + 1));
        memset(m[i1], '0', n2+1);
    }
    m[0][0] = '1';
    for (i1 = 1; i1 <= n1; i1 ++) {
        if (s1[i1-1] != s3[i1-1]) break;
        m[i1][0] = '1';
    }
    for (i2 = 1; i2 <= n2; i2 ++) {
        if (s2[i2-1] != s3[i2-1]) break;
        m[0][i2] = '1';
    }
    for (i1 = 1; i1 <= n1; i1 ++) {
        for (i2 = 1; i2 <= n2; i2 ++) {
            if (s1[i1-1] == s3[i1+i2-1]) {
                if (m[i1-1][i2] == '1')
                    m[i1][i2] = '1';
            }
            if (s2[i2-1] == s3[i1+i2-1]) {
                if (m[i1][i2-1] == '1')
                    m[i1][i2] = '1';
            }
        }
    }
    ans = m[n1][n2] == '1';
    for (i1 = 0; i1 <= n1; i1 ++) free(m[i1]);
    return ans;
}

bool isInterleave_dp2(char* s1, char* s2, char* s3) {
    int n1 = s1 == NULL ? 0 : strlen(s1);
    int n2 = s2 == NULL ? 0 : strlen(s2);
    int n3 = s3 == NULL ? 0 : strlen(s3);
    int i1 = 0, i2 = 0, ans = 0;
    char* m = NULL;
    if (n1+n2 != n3) return 0;
    m = (char*) malloc(sizeof(char) * (n2 + 2));
    memset(m, '0', n2+2);
    m[n2+1] = '\0';
    m[0] = '1';
    for (i2 = 1; i2 <= n2; i2 ++) {
        if (s2[i2-1] != s3[i2-1]) break;
        m[i2] = '1';
    }
    for (i1 = 1; i1 <= n1; i1 ++) {
        if (m[0] == '1' && s1[i1-1] != s3[i1-1])
            m[0] = '0';
        for (i2 = 1; i2 <= n2; i2 ++) {
            if (s2[i2-1] == s3[i1+i2-1] && m[i2-1] == '1') {
                m[i2] = '1';
            } else if (s1[i1-1] == s3[i1+i2-1] && m[i2] == '1') {
                m[i2] = '1';
            } else  m[i2] = '0';
        }
    }
    ans = m[n2] == '1';
    free(m);
    return ans;
}

bool isInterleave(char* s1, char* s2, char* s3) {
    return isInterleave_dp2(s1, s2, s3);
}

int main() {
    char* s1 = "aacaac";
    char* s2 = "aacaaeaac";
    char* s3 = "aacaaeaaeaacaac";
    printf("answer is %d\r\n", isInterleave_dp(s1, s2, s3));
    printf("answer is %d\r\n", isInterleave_recur(s1, s2, s3));    
    printf("answer is %d\r\n", isInterleave_dp2(s1, s2, s3));
    return 0;
}


Python Solution: github

#coding=utf-8

'''
    url: leetcode.com/problems/interleaving-string
    @author:     zxwtry
    @email:      zxwtry@qq.com
    @date:       2017年4月25日
    @details:    Solution: 92ms 18.64%
'''

class Solution(object):
    def isInterleave(self, s1, s2, s3):
        """
        :type s1: str
        :type s2: str
        :type s3: str
        :rtype: bool
        """
        n1 = 0 if s1 == None else len(s1)
        n2 = 0 if s2 == None else len(s2)
        n3 = 0 if s3 == None else len(s3)
        if n1+n2 != n3: return False
        dp = [[False for j in range(n2+1)] for i in range(n1+1)]
        dp[0][0] = True
        for j in range(1, n2+1):
            if n2[j-1] != s3[j-1]: break
            dp[0][j] = True
        for i in range(1, n1+1):
            if n1[i-1] != s3[i-1]: break
            dp[i][0] = True
        for i in range(1, n1+1):
            for j in range(1, n2+1):
                if s1[i-1] == s3[i+j-1] and dp[i-1][j]:
                    dp[i][j] = True
                if s2[j-1] == s3[i+j-1] and dp[i][j-1]:
                    dp[i][j] = True
        return dp[n1][n2]


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值