算法学习之动态规划(leetcode 87. Scramble String)
2017-04-08 15:48
603 查看
0x01题目
0x02解析
本题的目标是判断两个字符串之间的关系,正确的思路应该是使用遍历+分而治之的思想来做,若要判断两个字符串之间的关系,可以将两个字符串进行切割,判断切割后的子字符串之间的关系。
如果字符串s1[0, 1, … len-1]和s2[0, 1, …, len-1]满足scramble string条件(简称为SS条件),则有两种情况至少满足一种情况。
A. s1[0, 1, …i-1]和s2[0, 1, …i-1]满足SS条件且s1[i, len-1]和s2[i, len-1]满足SS条件
B. s1[0, 1, …i-1]和s2[len-i, len-1]满足SS条件且s1[i, len-1]和s2[0, 1, …len-i-1]满足SS条件
有两种解法:第一种递归,第二种动态规划,如代码所示。
0x03代码
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":
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".
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".
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.
0x02解析
本题的目标是判断两个字符串之间的关系,正确的思路应该是使用遍历+分而治之的思想来做,若要判断两个字符串之间的关系,可以将两个字符串进行切割,判断切割后的子字符串之间的关系。
如果字符串s1[0, 1, … len-1]和s2[0, 1, …, len-1]满足scramble string条件(简称为SS条件),则有两种情况至少满足一种情况。
A. s1[0, 1, …i-1]和s2[0, 1, …i-1]满足SS条件且s1[i, len-1]和s2[i, len-1]满足SS条件
B. s1[0, 1, …i-1]和s2[len-i, len-1]满足SS条件且s1[i, len-1]和s2[0, 1, …len-i-1]满足SS条件
有两种解法:第一种递归,第二种动态规划,如代码所示。
0x03代码
解法一 public class Solution { public boolean isScramble(String s1, String s2) { if(s1.equals(s2)) return true; if(s1.length() != s2.length()) return false; int len = s1.length(); int[] letters = new int[26]; for(int i = 0; i < len; i++){ letters[s1.charAt(i) - 'a']++; letters[s2.charAt(i) - 'a']--; } for(int i = 0; i < 26; i++){ if(letters[i] != 0){ return false; } } for(int i = 1; i < len; i++){ if(isScramble(s1.substring(0, i), s2.substring(0, i)) && isScramble(s1.substring(i), s2.substring(i)) ){ return true; } if(isScramble(s1.substring(0, i), s2.substring(len - i)) && isScramble(s1.substring(i), s2.substring(0, len - i)) ){ return true; } } return false; } }
解法二 /* 定义F(i, j, k)为S1[i..i + k - 1]和S2[j..j + k - 1]是否满足SS条件。 则需要遍历所有情况检查F(i, j, k)是否为真 S1 [ x1 | x2 ] i i + q i + k - 1 有以下两种可能性 S2 [ y1 | y2 ] j j + q j + k - 1 或者 S2 [ y1 | y2 ] j j + k - q j + k - 1 所以,当1 <= q < k时候, F(i, j, k) = ( F(i, j, q) AND F(i + q, j + q, k - q)) OR F(i, j + k - q, q) AND F(i + q, j, k - q) ) 当k = 1时 F(i, j, k) = (s1.charAt(i) == s2.charAt(j)); */ public class Solution { public boolean isScramble(String s1, String s2) { if (s1.length() != s2.length()) return false; int len = s1.length(); boolean [][][] F = new boolean[len][len][len + 1]; for (int k = 1; k <= len; ++k) for (int i = 0; i + k <= len; ++i) for (int j = 0; j + k <= len; ++j) if (k == 1) F[i][j][k] = (s1.charAt(i) == s2.charAt(j)); else for (int q = 1; q < k && !F[i][j][k]; ++q) { F[i][j][k] = ( F[i][j][q] && F[i + q][j + q][k - q]) || (F[i][j + k - q][q] && F[i + q][j][k - q]); } return F[0][0][len]; } }
相关文章推荐
- LeetCode之“动态规划”:Scramble String
- 算法学习之动态规划(leetcode 174. Dungeon Game)
- 算法学习之动态规划(leetcode 44 Wildcard Matching)
- 算法学习之动态规划(leetcode 85. Maximal Rectangle)
- google的面试题(三维动态规划的范例)——(87)Scramble String
- 算法学习之动态规划(leetcode 62. Unique Paths)
- 算法学习之动态规划(leetcode 304. Range Sum Query 2D - Immutable)
- 算法学习之动态规划(leetcode 91 Decode Ways)
- 算法学习之动态规划(leetcode 72. Edit Distance)
- 算法刷题心得:动态规划 scramble-string
- [LeetCode] Scramble String -- 三维动态规划的范例
- LeetCode: Scramble String [87]
- LeetCode 87 Scramble String
- leetcode[87]Scramble String
- 【算法学习笔记】23.动态规划 解题报告 SJTU OJ 1280 整装待发
- [Leetcode]@python 87. Scramble String.py
- leetcode 87. Scramble String 二分法
- leetcode 87: Scramble String
- LeetCode 87. Scramble String
- [leetcode] 87. Scramble String 解题报告