• leetcode 97:交错字符串


    package com.example.lettcode.dailyexercises;
    
    /**
     * @Class IsInterleave
     * @Description 97 交错字符串
     * 给定三个字符串 s1, s2, s3, 验证 s3 是否是由 s1 和 s2 交错组成的。
     * <p>
     * 示例 1:
     * 输入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
     * 输出: true
     * <p>
     * 示例 2:
     * 输入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc"
     * 输出: false
     * @Author
     * @Date 2020/7/18
     **/
    public class IsInterleave {
    }
    
    /**
     * error
     * 双指针
     * 这种方式有可能因为前面交替顺序不对,导致结果不对,应该加上回溯
     * s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
     * 当出现当前位置分别指向s1[5],s2[3],s3[8]时导致后面无法交替下去
     */
    /*    public static boolean isInterleave(String s1, String s2, String s3) {
    	boolean flag = false;
    	if (s3.length() != (s1.length() + s2.length())) return false;
    
    	int len1 = s1.length();
    	int len2 = s2.length();
    	int len3 = s3.length();
    	int p1 = 0, p2 = 0, p3 = 0;
    	while ((p1 < len1 || p2 < len2) && p3 < len3) {
    		if ((p1 < len1) && s3.charAt(p3) == s1.charAt(p1)) {
    			p3++;
    			p1++;
    		} else if ((p2 < len2) && s3.charAt(p3) == s2.charAt(p2)) {
    			p3++;
    			p2++;
    		} else {
    			return false;
    		}
    	}
    	return flag;
    }*/
    
    /**
     * 双指针+回溯
     */
    public static boolean isInterleave(String s1, String s2, String s3) {
    	if (s1.length() + s2.length() != s3.length()) return false;
    	return canMatch(s1, 0, s2, 0, s3, 0);
    }
    
    public static boolean canMatch(String s1, int p1, String s2, int p2, String s3, int p3) {
    	if (p3 >= s3.length()) return true;
    
    	if ((p1 < s1.length()) && (p3 < s3.length())
    			&& (s1.charAt(p1) == s3.charAt(p3))
    			&& (canMatch(s1, p1 + 1, s2, p2, s3, p3 + 1))) {
    		System.out.println(s1.charAt(p1) +" "+s3.charAt(p3));
    		return true;
    	}
    
    	if ((p2 < s2.length()) && (p3 < s3.length())
    			&& (s2.charAt(p2) == s3.charAt(p3))
    			&& (canMatch(s1, p1, s2, p2 + 1, s3, p3 + 1))) {
    		System.out.println(s2.charAt(p2) +" "+s3.charAt(p3));
    		return true;
    	}
    	return false;
    }
    
    /**
     * 动态规划:二维实现方式
     * dp[i][j] = dp[i-1][j] &&s1(i)=s3(i+j) 或者dp[i][j-1] &&s2[j]=s3[i+j]
     * dp[0][0] = true
     * 时间和空间复杂度均为O(MN)
     */
    public static boolean isInterleave(String s1, String s2, String s3) {
    	if (s3.length() != (s1.length() + s2.length())) return false;
    
    	int len1 = s1.length();
    	int len2 = s2.length();
    	// dp[i][j] 表示s1[i]和s2[j] 是否能交替组成s3[i+j]
    	boolean[][] dp = new boolean[len1 + 1][len2 + 1];
    	// 边界条件为啥是true,dp[0][1]/dp[1][0]可以为true,其前提条件之一是dp[0][0]为true
    	dp[0][0] = true;
    	for (int i = 0; i <= len1; ++i) {
    		for (int j = 0; j <= len2; ++j) {
    			int p = i + j - 1;      // s3的位置
    			//方式1--start,分别使用i>0 和j>0 是因为会有i>0&&j=0 或者i=0&&j>0 的情况
    //                if (i > 0) {
    //                    dp[i][j] = dp[i][j] || (dp[i - 1][j] && s1.charAt(i - 1) == s3.charAt(p));
    //                }
    //                if (j > 0) {
    //                    dp[i][j] = dp[i][j] || (dp[i][j - 1] && s2.charAt(j - 1) == s3.charAt(p));
    //                }
    			// 方式1--end
    			// 方式2--start
    			if (p < 0) continue;
    			// 使用这种方式会导致dp[0][0] 被修改为false,添加continue语句,可以避免这种情况
    			dp[i][j] = (((i > 0) && (dp[i - 1][j] && s1.charAt(i - 1) == s3.charAt(p)))
    					|| ((j > 0) && (dp[i][j - 1] && s2.charAt(j - 1) == s3.charAt(p))));
    			// 方式2--end
    		}
    	}
    	return dp[len1][len2];
    }
    
    /**
     * 动态规划优化空间: 滚动数组
     */
    public static boolean isInterleave(String s1, String s2, String s3) {
    	if (s3.length() != (s1.length() + s2.length())) return false;
    
    	int len1 = s1.length();
    	int len2 = s2.length();
    	// dp[j] 表示s1[i]和s2[j] 是否能交替组成s3[i+j]
    	boolean[] dp = new boolean[len2 + 1];
    	// 边界条件为啥是true,dp[1]可以为true,其前提条件之一是dp[0]为true
    	dp[0] = true;
    	for (int i = 0; i <= len1; ++i) {
    		for (int j = 0; j <= len2; ++j) {
    			int p = i + j - 1;      // s3的位置
    			if (p < 0) continue;
    			// 使用这种方式会导致dp[0]被修改为false,添加continue语句,可以避免这种情况
    			dp[j] = (((i > 0) && (dp[j] && s1.charAt(i - 1) == s3.charAt(p)))
    					|| ((j > 0) && (dp[j - 1] && s2.charAt(j - 1) == s3.charAt(p))));
    		}
    	}
    	return dp[len2];
    }
    
    public static void main(String[] args) {
    	String s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac";
    	boolean ans = isInterleave(s1, s2, s3);
    	System.out.println("IsInterleave demo01 result:" + ans);
    
    	s1 = "aabcc";
    	s2 = "dbbca";
    	s3 = "aadbbbaccc";
    	ans = isInterleave(s1, s2, s3);
    	System.out.println("IsInterleave demo02 result:" + ans);
    }
    
  • 相关阅读:
    Git工具提交github.com
    小程序-setData方法使用--改变默认数据data初始值方法
    小程序-全局变量
    小程序--获取openid
    小程序--错误{"errcode":40125,"errmsg":"invalid appsecret, view more at http://t.cn/RAEkdVq, hints: [ req_id: lE8J30972ns32 ]"}
    小程序-获取openid
    微信小程序--简易table表格
    微信小程序--简单页面跳转
    小程序禁止下拉更新
    小程序--登录获取code
  • 原文地址:https://www.cnblogs.com/fyusac/p/13336014.html
Copyright © 2020-2023  润新知