LeetCode--medium--scramble_string_87

summary:

divide and conquer | memorization

package myapp.kit.leetcode.top200;

import java.util.HashMap;
import java.util.Map;


/**
 * 87
 * hard
 *https://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.
 *
 * Example 1:
 *
 * Input: s1 = "great", s2 = "rgeat"
 * Output: true
 * Example 2:
 *
 * Input: s1 = "abcde", s2 = "caebd"
 * Output: false
 *
 "abcdefghijklmn"
 "efghijklmncadb"

 "abb"
 "bba"
 * @author huangdingsheng
 * @version 1.0, 2020/7/16
 */
public class scramble_string_87 {

    private static Map cache;

    // divide and conquer + memorization cache
    public static boolean isScramble(String s1, String s2) {
       cache = new HashMap<>();
       return search(s1, s2);
    }
    public static boolean search(String s1, String s2) {
        // cache
        if (cache.containsKey(s1 + "-" + s2)) {
            return cache.get(s1 + "-" + s2);
        }
        Boolean answer = false;
        if (s1.length() == 1) {
            answer = s1.equals(s2);
        } else {
            for (int i = 1; i < s1.length(); i++) {
                // divide program
                if (match(s1.substring(0, i), s2.substring(0, i))) {
                    answer = answer || (search(s1.substring(0, i), s2.substring(0, i)) && search(s1.substring(i), s2.substring(i)));
                }
                // pruning
                if (answer) {
                    continue;
                }
                if (match(s1.substring(i), s2.substring(0, s2.length() - i + 1))) {
                    answer = answer || (search(s1.substring(i), s2.substring(0, s2.length() - i)) && search(s1.substring(0, i), s2.substring(s2.length() - i)));
                }
            }
        }
        cache.put(s1 + "-" + s2, answer);
        return answer;
    }

    private static boolean match(String s1, String s2) {
        int[] arr = new int[26];
        for (int i = 0; i < s1.length(); i++) {
            arr[s1.charAt(i) - 'a']++;
            arr[s2.charAt(i) - 'a']--;
        }
        for (int i : arr) {
            if (i != 0) {
                return false;
            }
        }
        return true;
    }


    public static void main(String[] args) {
       // System.out.println(match("abcde", "absda"));
        System.out.println(isScramble("abcdefghijklmn", "efghijklmncadb"));
    }


}

 

你可能感兴趣的:(LeetCode)