0
点赞
收藏
分享

微信扫一扫

动态规划---例题详解篇(入门-深入)

1.数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

示例 1:

输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]
示例 2:

输入:n = 1
输出:["()"]

class Solution {

    public List<String> res = new ArrayList<>();

    public List<String> generateParenthesis(int n) {

        dfs(0,0,n,"");
        return res;
    }

    public void dfs(int leftCount,int rightCount,int n,String sum) {

        
        if(leftCount > n || rightCount > n || rightCount > leftCount)
        return;

        if(leftCount == n && rightCount == n) {

            res.add(sum);
            return;
        }
        
        dfs(leftCount+1,rightCount,n,sum+"(");
        dfs(leftCount,rightCount + 1,n,sum + ")");
    }
}

2.给定三个字符串 s1、s2、s3,请你帮忙验证 s3 是否是由 s1 和 s2 交错 组成的。

两个字符串 s 和 t 交错 的定义与过程如下,其中每个字符串都会被分割成若干 非空 子字符串:

s = s1 + s2 + ... + sn
t = t1 + t2 + ... + tm
|n - m| <= 1
交错 是 s1 + t1 + s2 + t2 + s3 + t3 + ... 或者 t1 + s1 + t2 + s2 + t3 + s3 + ...
注意:a + b 意味着字符串 a 和 b 连接。

 (1)使用二维数组

class Solution {
    public boolean isInterleave(String s1, String s2, String s3) {

        int n = s1.length();
        int m = s2.length();
        int p = s3.length();

        if(n + m != p)
        return false;

        //f[i][j]表示用s1的前i个字符和用s2的前i个字符是否能符合s3的前(i + j - 1)个字符
        boolean[][] f = new boolean[n + 1][m + 1];
        f[0][0] = true;

        for(int i = 0;i <= n;i++) {

            for(int j = 0;j <= m;j++) {

                int q = i + j - 1;
                if(i > 0) {

                    //f[i][j] = f[i][j] || (f[i - 1][j] && s3.charAt(q) == s1.charAt(i - 1));
                    //原题是以上的形式,速度慢了一半
                    //这里的f[i][j] = f[i][j]只是因为j要从0开始,告诉j我i能满足,已经不需要你了
                    
                    f[i][j] = (f[i - 1][j] && s3.charAt(q) == s1.charAt(i - 1));
                }

                if(j > 0) {
                    f[i][j] = f[i][j] || (f[i][j - 1] && s2.charAt(j - 1) == s3.charAt(q));
                }
            }
        }

        return f[n][m];
    }
}

(2)使用一维数组进行优化

class Solution {
    public boolean isInterleave(String s1, String s2, String s3) {
        int n = s1.length(), m = s2.length(), t = s3.length();

        if (n + m != t) {
            return false;
        }

        boolean[] f = new boolean[m + 1];

        f[0] = true;
        for (int i = 0; i <= n; ++i) {
            for (int j = 0; j <= m; ++j) {
                int p = i + j - 1;
                if (i > 0) {
                    f[j] = f[j] && s1.charAt(i - 1) == s3.charAt(p);
                }
                if (j > 0) {
                    f[j] = f[j] || (f[j - 1] && s2.charAt(j - 1) == s3.charAt(p));
                }
            }
        }

        return f[m];
    }
}

(3)动态规划模板

class Solution {
    public boolean isInterleave(String s1, String s2, String s3) {

        if(s1 == null || s2 == null || s3 == null)
        return false;

        char[] a = s1.toCharArray();
        char[] b = s2.toCharArray();
        char[] c = s3.toCharArray();

        if(s1.length() + s2.length() != s3.length())
        return false;

        boolean[][] dp = new boolean[s1.length() + 1][s2.length() + 1];
        dp[0][0] = true;

        for(int i = 1;i <= s1.length();i++) {

            if(s1.charAt(i - 1) != s3.charAt(i - 1))
            break;

            dp[i][0] = true;
        }

        for(int i = 1;i <= s2.length();i++) {

            if(s2.charAt(i - 1) != s3.charAt(i - 1))
            break;

            dp[0][i] = true;
        }


        for(int i = 1;i <= s1.length();i++) {

            for(int j = 1;j <= s2.length();j++) {

                if((a[i - 1] == c[i + j - 1] && dp[i -1][j]) || (b[j - 1] == c[i + j - 1] && dp[i][j - 1])) {

                    dp[i][j] = true;
                }
            }
        }

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

相关推荐

0 条评论