2021-08-18:扰乱字符串。使用下面描述的算法可以扰乱字符串 s 得到字符串 t :1.如果字符串的长度为 1 ,算法停止。2.如果字符串的长度 > 1 ,执行下述步骤:在一个随机下标处将字符串分割成两个非空的子字符串。即,如果已知字符串 s ,则可以将其分成两个子字符串 x 和 y ,且满足 s = x + y 。随机 决定是要「交换两个子字符串」还是要「保持这两个子字符串的顺序不变」。即,在执行这一步骤之后,s 可能是 s = x + y 或者 s = y + x 。在 x 和 y 这两个子字符串上继续从步骤 1 开始递归执行此算法。给你两个 长度相等 的字符串 s1 和 s2,判断 s2 是否是 s1 的扰乱字符串。如果是,返回 true ;否则,返回 false 。

福大大 答案2021-08-18:

样本对应模型。递归分割字符串 s 和字符串 t 。分割时,s左长度=s右长度,t左长度=t右长度。

代码用golang编写。代码如下:

package main

import "fmt"

func main() {
    s1 := "abcd"
    s2 := "dcba"
    ret := isScramble0(s1, s2)
    fmt.Println(ret)
}

func isScramble0(s1 string, s2 string) bool {
    if (s1 == "" && s2 != "") || (s1 != "" && s2 == "") {
        return false
    }
    if s1 == "" && s2 == "" {
        return true
    }
    if s1 == s2 {
        return true
    }
    if !sameTypeSameNumber(s1, s2) {
        return false
    }
    return process0(s1, 0, len(s1)-1, s2, 0, len(s2)-1)
}

// str1[L1...R1] str2[L2...R2] 是否互为玄变串
// 一定保证这两段是等长的!
func process0(str1 string, L1 int, R1 int, str2 string, L2 int, R2 int) bool {
    if L1 == R1 {
        return str1[L1] == str2[L2]
    }
    for leftEnd := L1; leftEnd < R1; leftEnd++ {
        p1 := process0(str1, L1, leftEnd, str2, L2, L2+leftEnd-L1) && process0(str1, leftEnd+1, R1, str2, L2+leftEnd-L1+1, R2)
        p2 := process0(str1, L1, leftEnd, str2, R2-(leftEnd-L1), R2) && process0(str1, leftEnd+1, R1, str2, L2, R2-(leftEnd-L1)-1)
        if p1 || p2 {
            return true
        }
    }
    return false
}

func sameTypeSameNumber(str1 string, str2 string) bool {
    if len(str1) != len(str2) {
        return false
    }
    map0 := make([]int, 256)
    for i := 0; i < len(str1); i++ {
        map0[str1[i]]++
    }
    for i := 0; i < len(str2); i++ {
        map0[str2[i]]--
        if map0[str2[i]] < 0 {
            return false
        }
    }
    return true
}

执行结果如下:
图片


左神java代码