动态规划:
http://www.sohu.com/a/153858619_466939
https://blog.csdn.net/u013309870/article/details/75193592
首先,需要解决的问题要满足:最优子结构,即“可以利用子问题的最优解获得整个问题的最优解”。
其次,需要找出问题的边界,相当于初始值。
最后,还需要找到问题的状态转移方程,这是动态规划问题的核心,决定了问题的每一个阶段和下一个阶段之间的关系。
若采用递归算法,时间和空间复杂度都将与递归深度有关,所以可以使用备忘录算法,即将每次遇到不同参数的计算结果先保存起来,在递归或循环时先寻找有无相同参数的结果,无再继续计算。此方法可以避免大量的重复计算。
除此之外,还可以尝试将思路逆转,将自顶向下的求解过程转换为自底向上的求解。通常思路是先假设已经获得最优解,然后一步一步将最优解拆分;逆转后从0开始一点一点大建整个框架从而找到联系,求出最优解。
递归法:F(s,p)
算法:
(1)若p
为空:s
为空则返回true
,否则返回false
(2)若p
的长度为1:当且仅当s
长度为1,且首字母匹配的时候返回true
。否则返回false
(3)若p
的第二个字符不为*
:
s
为空则返回false
- 当字母匹配的时候,递归调用
F(s-1,p-1)
- 否则返回
false
(4)若p
的第二个字符为*
:
若s
不为空,且首字母匹配则一直循环:{若递归调用F(s,p-2)
返回true
,则返回true
;否则s = s-1
}
(5)递归调用F(s,p-2)
// 递归法
public static boolean isMatch(String s, String p) {
// 都为空
if (p.isEmpty())
if (s.isEmpty())
return true;
else
return false;
// p长度为1
if (p.length() == 1) {
if (s.length() == 1) {
if (p.charAt(0) == s.charAt(0) || p.charAt(0) == '.')
return true;
else
return false;
} else {
return false;
}
}
// p第二个字符不为*
if (p.charAt(1) != '*') {
if (s.isEmpty())
return false;
else if (p.charAt(0) == s.charAt(0) || p.charAt(0) == '.')
return isMatch(s.substring(1), p.substring(1));
else
return false;
}
// p第二个字符为*
else {
while (!s.isEmpty() && (p.charAt(0) == s.charAt(0) || p.charAt(0) == '.')) {
if (isMatch(s, p.substring(2)))
return true;
s = s.substring(1);
}
}
return isMatch(s, p.substring(2));
}
// 递归法(简化写法)
public static boolean isMatch2(String s, String p) {
// 都为空
if (p.isEmpty())
return s.isEmpty();
// p长度为1
if (p.length() == 1) {
return (s.length() == 1&&(p.charAt(0) == s.charAt(0) || p.charAt(0) == '.'));
}
// p第二个字符不为*
if (p.charAt(1) != '*') {
if (s.isEmpty())
return false;
else
return (p.charAt(0) == s.charAt(0) || p.charAt(0) == '.')&&isMatch(s.substring(1), p.substring(1));
}
// p第二个字符为*
else {
while (!s.isEmpty() && (p.charAt(0) == s.charAt(0) || p.charAt(0) == '.')) {
if (isMatch(s, p.substring(2)))
return true;
s = s.substring(1);
}
}
return isMatch(s, p.substring(2));
}
将上述算法简化如下:
(1)若p
为空:s
为空则返回true
,否则返回true
(2)若p
的长度大于1,且p
的第二个字符为*
:
- 若递归调用
F(s,p-2)
返回true
,则返回true
- 否则在首字母匹配,且递归调用
F(s-1,p)
返回true
时,才返回true
。否则返回false
(3)其余情况:当且仅当s
不为空,且首字母匹配,且递归调用F(s-1,p-1)
返回true
时,才返回true
。否则返回false
public boolean isMatch(String s, String p) {
if (p.isEmpty()) return s.isEmpty();
if (p.length() > 1 && p.charAt(1) == '*') {
return isMatch(s, p.substring(2))
|| (!s.isEmpty() && (p.charAt(0) == s.charAt(0) || p.charAt(0) == '.')
&& isMatch(s.substring(1), p));
}
return !s.isEmpty() && (p.charAt(0) == s.charAt(0) || p.charAt(0) == '.')
&& isMatch(s.substring(1), p.substring(1));
}