[题解][LeetCode][Scramble String]
2014-07-30 14:47
351 查看
题目:
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 =
To scramble the string, we may choose any non-leaf node and swap its two children.
For example, if we choose the node
produces a scrambled string
We say that
Similarly, if we continue to swap the children of nodes
it produces a scrambled string
We say that
Given two strings s1 and s2 of the same length, determine if s2 is a scrambled string of s1.
题解:
三维动态规划+剪枝优化
思路是,若两个string互为scrambled,那么一定能找到一个分割点,s1左与s2左为scrambled,s1右和s2右为scrambled。
因为可以左右交换,所以也可能是 s1左 与 s2右 为scrambled,s1右 和 s2左 为scrambled。
所以我们要做的就是枚举这个分界点。
可选的办法是递归,也可以用动态规划来做。
设t3[k][i][j],True表示两个子串互为scrambled。三维分别意为,k是子串的长度,i是s1子串的起点,j是s2子串的起点。
即,两个子串分别为,i...i+k-1, j...j+k-1
依次枚举k, i, j, 以及分界点h
for k in range(2,n+1) :
for i in range(n-k+1)[::-1] :
for j in range(n-k+1)[::-1] :
for h in range(1,k) :
LeetCode上面时间限制的比较厉害。若是要AC,还需要两个剪枝:
1. 如果两个子串连所含的字母都不一样,那么continue,跳过,枚举下一个子串。
2. 如果已经找到当前两个子串一个正确的划分点,那么break,跳过剩下的枚举
Code:
参考:
http://blog.csdn.net/fightforyourdream/article/details/17707187 http://www.blogjava.net/sandy/archive/2013/05/22/399605.html
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.
题解:
三维动态规划+剪枝优化
思路是,若两个string互为scrambled,那么一定能找到一个分割点,s1左与s2左为scrambled,s1右和s2右为scrambled。
因为可以左右交换,所以也可能是 s1左 与 s2右 为scrambled,s1右 和 s2左 为scrambled。
所以我们要做的就是枚举这个分界点。
可选的办法是递归,也可以用动态规划来做。
设t3[k][i][j],True表示两个子串互为scrambled。三维分别意为,k是子串的长度,i是s1子串的起点,j是s2子串的起点。
即,两个子串分别为,i...i+k-1, j...j+k-1
依次枚举k, i, j, 以及分界点h
for k in range(2,n+1) :
for i in range(n-k+1)[::-1] :
for j in range(n-k+1)[::-1] :
for h in range(1,k) :
LeetCode上面时间限制的比较厉害。若是要AC,还需要两个剪枝:
1. 如果两个子串连所含的字母都不一样,那么continue,跳过,枚举下一个子串。
2. 如果已经找到当前两个子串一个正确的划分点,那么break,跳过剩下的枚举
Code:
class Solution: # @return a boolean def isScramble(self, s1, s2): if len(s1) != len(s2): return False n = len(s1) if n == 0: return True a = set(s1) b = set(s2) if a != b: return False t3=[[[False for i in range(n+1)] for i in range(n+1)]for i in range(n+1)] for i in range(n): for j in range(n): t3[1][i][j] = s1[i] is s2[j] for k in range(2,n+1) : for i in range(n-k+1)[::-1] : l1 = list(s1[i:i+k]) l1.sort() for j in range(n-k+1)[::-1] : l2 = list(s2[j:j+k]) l2.sort() if l1 != l2: continue for h in range(1,k) : t3[k][i][j] = t3[k][i][j] or (t3[h][i][j] and t3[k-h][i+h][j+h]) or (t3[h][i][j+k-h] and t3[k-h][i+h][j]) if t3[k][i][j]: break return t3 [0][0]
参考:
http://blog.csdn.net/fightforyourdream/article/details/17707187 http://www.blogjava.net/sandy/archive/2013/05/22/399605.html
相关文章推荐
- [LeetCode]题解(python):087-Scramble String
- 【leetcode题解】3 - Scramble String
- LeetCode 97. Interleaving String 题解
- 【一天一道LeetCode】#87. Scramble String
- [leetcode]Scramble String
- [Leetcode] Scramble String
- leetcode 087 —— Scramble String
- LeetCode Scramble String
- leetcode 87: Scramble String
- LeetCode Scramble String
- leetcode -- Scramble String -- 重点
- LeetCode: Scramble String
- Leetcode87. Scramble String
- LeetCode: Scramble String
- 【LeetCode】Scramble String
- 【一天一道LeetCode】#87. Scramble String
- LeetCode 笔记系列 19 Scramble String [合理使用递归]
- LeetCode --- 87. Scramble String
- leetcode 87: Scramble String
- Leetcode 87. Scramble String