【LeetCode】Scramble String 解题报告

【题目】

Given a string s1, we may represent it as a binary tree by partitioning it to two non-empty substrings recursively.

Below is one possible representation of s1 = "great":

    great
   /    \
  gr    eat
 / \    /  \
g   r  e   at
           / \
          a   t

To scramble the string, we may choose any non-leaf node and swap its two children.

For example, if we choose the node "gr" and swap its two children, it produces a scrambled string "rgeat".

    rgeat
   /    \
  rg    eat
 / \    /  \
r   g  e   at
           / \
          a   t

We say that "rgeat" is a scrambled string of "great".

Similarly, if we continue to swap the children of nodes "eat" and "at", it produces a scrambled string "rgtae".

    rgtae
   /    \
  rg    tae
 / \    /  \
r   g  ta  e
       / \
      t   a

We say that "rgtae" is a scrambled string of "great".

Given two strings s1 and s2 of the same length, determine if s2 is a scrambled string of s1.

【解析】

题意:判断两个字符串是否能通过二叉树的左右子树交换相等。

【递归解法】

其实也是暴力遍历,把s1,s2分别分成两部分,判断s1的两部分和s2的两部分是否分别可以交换相等。

public class Solution {
    public boolean isScramble(String s1, String s2) {
        if (s1.length() != s2.length()) return false;
        if (s1.equals(s2)) return true;
        char[] c1 = s1.toCharArray();
        char[] c2 = s2.toCharArray();
        Arrays.sort(c1);
        Arrays.sort(c2);
        if (!Arrays.equals(c1, c2)) return false;
        for (int i = 1; i < s1.length(); i++) {
            if (isScramble(s1.substring(0, i), s2.substring(0, i)) && isScramble(s1.substring(i), s2.substring(i))) return true;
            if (isScramble(s1.substring(0, i), s2.substring(s2.length() - i)) && isScramble(s1.substring(i), s2.substring(0, s2.length() - i))) return true;
        }
        return false;
    }
}

参考:https://leetcode.com/discuss/3632/any-better-solution

【动态规划解法】

这道题用二维数组来存储中间结果已经不行了,需要一个三维数组 dp[i][j][len],表示从s1的第i个字符开始长度为len的子串,和从s2的第j个字符开始长度为len的子串,是否互为scramble。

初始化为dp[i][j][1] = s1.charAt(i) == s2.charAt(j),即长度为1的子串是否互为scramble。

三维数组就要三层循环,最终结果为dp[0][0][s1.length()],即从s1的第0个字符开始长度为s1.length()的子串,即s1本身和s2本身是否互为scramble。

要判断dp[i][j][len]的值,就要把s1从i开始长度为len的串分别从k=1, 2 ... len-1处切开,判断切成的两半和s2同样切成的两半是否互为scramble,只要有一种切法满足条件,那么dp[i][j][len]就为true,否则为false。

public class Solution {
    public boolean isScramble(String s1, String s2) {
        if (s1.length() != s2.length()) return false;
        if (s1.equals(s2)) return true;
        
        boolean[][][] dp = new boolean[s1.length()][s2.length()][s1.length() + 1];
        for (int i = 0; i < s1.length(); i++) {
            for (int j = 0; j < s2.length(); j++) {
                dp[i][j][1] = s1.charAt(i) == s2.charAt(j);
            }
        }
        
        for (int len = 2; len <= s1.length(); len++) {
            for (int i = 0; i < s1.length() - len + 1; i++) {
                for (int j = 0; j < s2.length() - len + 1; j++) {
                    for (int k = 1; k < len; k++) {
                        dp[i][j][len] |= dp[i][j][k] && dp[i + k][j + k][len - k] || dp[i][j + len - k][k] && dp[i + k][j][len - k];
                    }
                }
            }
        }
        
        return dp[0][0][s1.length()];
    }
}

参考:http://blog.csdn.net/linhuanmars/article/details/24506703 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 类leetcode算法在线编译的答题系统源码可以包含以下几个关键部分: 1. 用户认证和管理:系统需要提供用户认证功能,允许用户进行注册、登录和注销操作。可以使用数据库存储用户信息,并对密码进行加密保护。通过认证,用户可以保存和管理自己的答题记录和排名。 2. 题目管理:系统需要提供题目的增删改查功能。每个题目包含一个标题、题目描述、输入要求、输出要求和示例等信息。可以使用数据库存储题目信息,并提供相应的接口供管理员进行管理。 3. 代码编辑和编译:系统需要提供一个代码编辑器,让用户可以编写算法代码。编辑器需要支持常见的编程语言,如C++、Java、Python等,并提供语法高亮和自动补全等功能。用户可以在编辑器中编写代码,并进行编译和运行测试。 4. 测试用例和结果判断:系统需要提供一个测试用例管理功能,允许管理员为每个题目设置多个测试用例。用户可以选择运行自己的代码,并查看运行结果。系统会自动判断用户代码的输出是否符合预期结果,并给出相应的反馈。 5. 答题记录和排名:系统需要记录用户的答题记录,包括题目信息、提交时间、编译结果和运行结果等。用户可以查看自己的答题记录,同时系统也会根据答题情况进行排名,展示最高得分和排名前几名的用户信息。 6. 用户交流和讨论:系统可以提供一个讨论区或论坛功能,供用户之间互相交流和提问。用户可以就题目的解法、算法思路等进行讨论,并给出相应的评论和回答。 以上是一个类leetcode算法在线编译的答题系统源码的基本结构和功能要求。具体实现可以根据需求进行适当调整和拓展。 ### 回答2: 类leetcode算法在线编译的答题系统源码是一个用于提供算法练习和在线编译运行的系统。该系统以类似leetcode的方式,提供了一系列算法题目,并给出了题目描述和输入输出示例。 源码中的核心功能包括题目列表、题目详情、代码编辑和编译运行等功能。用户可以在题目列表页面选择自己想要练习的题目,点击进入题目详情页面查看题目描述和示例。在代码编辑页面,用户可以输入自己的解答代码,并点击编译运行按钮执行代码,并查看运行结果。 在源码编写过程中,需要使用一些必要的技术和工具。前端开发可以使用HTML、CSS和JavaScript,通过前端框架进行页面布局和交互处理,提供用户友好的界面。后端开发可以使用一种后端框架,如node.js或Python等,设计数据库模型和处理请求的逻辑。同时需要使用一种编译器或解释器,支持对用户输入的代码进行编译运行,并返回结果。 在源码的实现过程中,需要考虑安全性和容错性。为了防止用户恶意代码或非法操作,可以使用输入验证和代码沙箱技术对用户输入进行过滤和安全检查。对于异常情况,可以通过异常处理机制捕获并给出相应的错误提示信息。 总之,类leetcode算法在线编译的答题系统源码应当具备题目管理、代码编辑和编译运行功能,并注意安全性和用户友好性。通过实现这样一个系统,可以帮助用户提升算法能力并加深对编程语言的理解和应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值