【Scramble String】cpp

题目:

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.

代码:

class Solution {
public:
    bool isScramble(string s1, string s2) {
            const int n1 = s1.size();
            const int n2 = s2.size();
            if (n1!=n2) { return false; }
            const int n = n1;
            int alpha[26] = {0};
            for ( int i=0; i<n; ++i ){ alpha[s1[i]-‘a‘]++; alpha[s2[i]-‘a‘]--; }
            for ( int i=0; i<26; ++i ){ if ( alpha[i]!=0 ) return false; }
            // terminal condition
            if ( n==1 ) return s1[0]==s2[0];
            // recursive process
            for ( int i=1; i<n; ++i ){
                //cout << s1 << "," << s2 << ":" << i << endl;
                if (
                    (
                        Solution::isScramble(s1.substr(0,i), s2.substr(0,i)) &&
                          Solution::isScramble(s1.substr(i,n-i), s2.substr(i,n-i))
                    )
                       ||
                    (
                        Solution::isScramble(s1.substr(0,i), s2.substr(n-i,i)) &&
                          Solution::isScramble(s1.substr(i,n-i), s2.substr(0,n-i))
                    )
                   )
                   { return true; }
            }
            return false;
    }
};

tips:

这道题的题意自己并没有理解好,引用一个网上其他人的理解如下:

http://www.blogjava.net/sandy/archive/2013/05/22/399605.html

由于一个字符串有很多种二叉表示法,貌似很难判断两个字符串是否可以做这样的变换。
“对付复杂问题的方法是从简单的特例来思考,从而找出规律。
先考察简单情况:
字符串长度为1:很明显,两个字符串必须完全相同才可以。
字符串长度为2:当s1="ab", s2只有"ab"或者"ba"才可以。
对于任意长度的字符串,我们可以把字符串s1分为a1,b1两个部分,s2分为a2,b2两个部分,满足((a1~a2) && (b1~b2))或者 ((a1~b2) && (a1~b2))”

理解了题意,代码也就写出来了。

具体还有几个细节需要注意:

1. 为了剪枝并加快速度,做了如下几件事情:

  a) 判断s1与s2的长度是否相等

  b) 判断s1与s2的每个字符数量是否相等(这里由于是字母所以用一个定长数组alpha[26]表示:某个字母在s1中出现一次+1,在s2中出现一次-1;最终alpha的每个元素都是0则证明s1与s2的每个字符数量相等。扩展一下,如果字符不止26个字母,包含其他字符呢?可以用hashmap表示)

2. 设定终止条件:

  如果s1和s2长度已经为1,无法再分割了,就直接比较即可。

3. 在递归传入参数的时候,用到了substr(begin, num):

  a) begin代表切取的第一个字符下标,num代表截取几个字符

  b) 注意每次传入isScramble的字符长度相等

===========================================

上述的做法类似记忆化搜索,网上还有一种动态规划的解法,也学习了吧。

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

时间: 2024-11-06 11:28:27

【Scramble String】cpp的相关文章

【Interleaving String】cpp

题目: Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. For example,Given:s1 = "aabcc",s2 = "dbbca", When s3 = "aadbbcbcac", return true.When s3 = "aadbbbaccc", return false. 代码: “merge sor

【Word Break】cpp

题目: Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words. For example, givens = "leetcode",dict = ["leet", "code"]. Return true becau

【Text Justification】cpp

题目: Given an array of words and a length L, format the text such that each line has exactly L characters and is fully (left and right) justified. You should pack your words in a greedy approach; that is, pack as many words as you can in each line. Pa

【Simplify Path】cpp

题目: Given an absolute path for a file (Unix-style), simplify it. For example,path = "/home/", => "/home"path = "/a/./b/../../c/", => "/c" click to show corner cases. Corner Cases: Did you consider the case whe

【Implement strStr() 】cpp

题目: Implement strStr(). Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack. Update (2014-11-02):The signature of the function had been updated to return the index instead of the pointer. If you st

【Valid Palindrome】cpp

题目: Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases. For example,"A man, a plan, a canal: Panama" is a palindrome."race a car" is not a palindrome. Note:Have you consider tha

【Distinct Subsequences】cpp

题目: Given a string S and a string T, count the number of distinct subsequences of T in S. A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relat

【实用类String】String类方法的应用案例:查找判断指定字符出现的次数和位置

一.应用要求 输入一个字符串,再输入要查找的字符,判断该字符在该字符串中出现的次数. 二.实现思路 1.使用substring()方法将字符串的每个字符存入数组 2.比较数组每个字符是否与指定的字符相等,并计数 三.编写代码 错误案例: 1 import java.util.Scanner; 2 3 public class StringDemo { 4 5 public static void main(String[] args) { 6 Scanner input = new Scanne

【Palindrome Number】cpp

题目: Determine whether an integer is a palindrome. Do this without extra space. click to show spoilers. Some hints: Could negative integers be palindromes? (ie, -1) If you are thinking of converting the integer to string, note the restriction of using