leetcode — scramble-string

import java.util.Arrays;

/**
 * Source : https://oj.leetcode.com/problems/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.
 *
 */
public class ScrambleString {

    /**
     * s1是不是s2的一个scramblestring
     * s1按照任意位置进行二分划分,一直递归下去,期间,可以交换非叶子节点的两个子节点左右顺序,一直到叶子节点
     *
     * 一开始想着是找到s1的所有scramblestring,然后判断s2是否在里面
     * 但是其实在寻找s2的scramblestring的时候就可以和s2进行对比判断,而不需要存储所有的scramblestring
     *
     * 选择
     * s1分割的位置,递归的进行如下判断
     * s1在i左边的子串和s2在i左边的子串是scramble的,s1在i的右边的子串和s2在i右边的子串是scramble的,或者
     * s1在i左边的子串和s2在i右边的子串是scramble的,s1在i的右边的子串和s2在i左边的子串是scramble的
     *
     * @param s1
     * @param s2
     */
    public boolean scramble (String s1, String s2) {
        if (s1.length() != s2.length()) {
            return false;
        }
        if (s1.length() <= 1) {
            return s1.equals(s2);
        }
//        return recursion(s1, s2);
        return recursion1(s1, s2);
    }

    public boolean recursion (String s1, String s2) {
        int len = s1.length();
        if (len == 1) {
            return s1.equals(s2);
        }
        for (int i = 1; i < len; i++) {
            if ((recursion(s1.substring(0, i), s2.substring(0, i)) && recursion(s1.substring(i), s2.substring(i)))
                    || (recursion(s1.substring(0,i), s2.substring(len-i)) && recursion(s1.substring(i), s2.substring(0,len-i)))) {
                return true;
            }
        }
        return false;
    }

    /**
     * 递归的时候有些分支是不必要的,可以剪裁分支
     * 在递归的时候,对s1和s2进行排序,如果排序之后两个字符串不相等则不必要继续递归
     *
     * @param s1
     * @param s2
     * @return
     */
    public boolean recursion1 (String s1, String s2) {
        int len = s1.length();
        if (len == 1) {
            return s1.equals(s2);
        }
        char[] s1CharArr = s1.toCharArray();
        Arrays.sort(s1CharArr);
        String sortedS1 = new String(s1CharArr);
        char[] s2CharArr = s2.toCharArray();
        Arrays.sort(s2CharArr);
        String sortedS2 = new String(s1CharArr);
        if (!sortedS1.equals(sortedS2)) {
            return false;
        }

        for (int i = 1; i < len; i++) {
            if ((recursion(s1.substring(0, i), s2.substring(0, i)) && recursion(s1.substring(i), s2.substring(i)))
                    || (recursion(s1.substring(0,i), s2.substring(len-i)) && recursion(s1.substring(i), s2.substring(0,len-i)))) {
                return true;
            }
        }
        return false;
    }

    /**
     * 递归的时候会有一些重复计算,使用数组记录计算过的结果,每次递归的时候判断,如果已经计算过则直接使用计算过的结果
     * 中间结果需要一个三维的boolean数组,因为,每次计算结果的变量是s1.index1,s2.index2,还有当前字符串的长度len
     *
     * @param s1
     * @param s2
     * @return
     */
    public boolean scramble2 (String s1, String s2) {
        if (s1.length() != s2.length()) {
            return false;
        }
        if (s1.length() <= 1) {
            return s1.equals(s2);
        }
        int[][][] calculated = new int[s1.length()][s2.length()][s1.length()];
        for (int i = 0; i < s1.length(); i++) {
            for (int j = 0; j < s2.length(); j++) {
                Arrays.fill(calculated[i][j], -1);
            }
        }
        return recursion(s1, s2);
    }

    public boolean recursion2 (String s1, int index1, String s2, int index2, int len, int[][][] calculated) {
        if (len == 1) {
            return s1.charAt(index1) == s2.charAt(index2);
        }
        int preresult = calculated[index1][index1][len-1];
        if (preresult != -1) {
            return preresult == 1;
        }
        preresult = 0;
        for (int i = 1; i < len; i++) {
            if (recursion2(s1, index1, s2, index2, i, calculated)
                    && recursion2(s1, index1 + 1, s2, index2 + 1, len - i, calculated)) {
                preresult = 1;
                break;
            }
            if (recursion2(s1, index1, s2, index2 + len - i, i,  calculated)
                    && recursion2(s1, index1 + 1, s2, index2, len - i, calculated)) {
                preresult = 1;
                break;
            }
        }
        calculated[index1][index2][len-1] = preresult;
        return preresult == 1;
    }




    public static void main(String[] args) {
        ScrambleString scrambleString = new ScrambleString();
        System.out.println(scrambleString.scramble("great", "rgtae"));
        System.out.println(scrambleString.scramble2("great", "rgtae"));
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
项目:使用AngularJs编写的简单 益智游戏(附源代码)  这是一个简单的 javascript 项目。这是一个拼图游戏,也包含一个填字游戏。这个游戏玩起来很棒。有两个不同的版本可以玩这个游戏。你也可以玩填字游戏。 关于游戏 这款游戏的玩法很简单。如上所述,它包含拼图和填字游戏。您可以通过移动图像来玩滑动拼图。您还可以选择要在滑动面板中拥有的列数和网格数。 另一个是填字游戏。在这里你只需要找到浏览器左侧提到的那些单词。 要运行此游戏,您需要在系统上安装浏览器。下载并在代码编辑器中打开此项目。然后有一个 index.html 文件可供您修改。在命令提示符中运行该文件,或者您可以直接运行索引文件。使用 Google Chrome 或 FireFox 可获得更好的用户体验。此外,这是一款多人游戏,双方玩家都是人类。 这个游戏包含很多 JavaScript 验证。这个游戏很有趣,如果你能用一点 CSS 修改它,那就更好了。 总的来说,这个项目使用了很多 javascript 和 javascript 库。如果你可以添加一些具有不同颜色选项的级别,那么你一定可以利用其库来提高你的 javascript 技能。 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。
LeetCode-Editor是一种在线编码工具,它提供了一个用户友好的界面编写和运行代码。在使用LeetCode-Editor时,有时候会出现乱码的问题。 乱码的原因可能是由于编码格式不兼容或者编码错误导致的。在这种情况下,我们可以尝试以下几种解决方法: 1. 检查文件编码格式:首先,我们可以检查所编辑的文件的编码格式。通常来说,常用的编码格式有UTF-8和ASCII等。我们可以将编码格式更改为正确的格式。在LeetCode-Editor中,可以通过界面设置或编辑器设置来更改编码格式。 2. 使用正确的字符集:如果乱码是由于使用了不同的字符集导致的,我们可以尝试更改使用正确的字符集。常见的字符集如Unicode或者UTF-8等。在LeetCode-Editor中,可以在编辑器中选择正确的字符集。 3. 使用合适的编辑器:有时候,乱码问题可能与LeetCode-Editor自身相关。我们可以尝试使用其他编码工具,如Text Editor、Sublime Text或者IDE,看是否能够解决乱码问题。 4. 查找特殊字符:如果乱码问题只出现在某些特殊字符上,我们可以尝试找到并替换这些字符。通过仔细检查代码,我们可以找到导致乱码的特定字符,并进行修正或替换。 总之,解决LeetCode-Editor乱码问题的方法有很多。根据具体情况,我们可以尝试更改文件编码格式、使用正确的字符集、更换编辑器或者查找并替换特殊字符等方法来解决这个问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值