这个模板适用于给出一个字符串,然后从字符串中判断其子字符串是否满足某一性质。
比如:
93. 复原IP地址
题目给出一个字符串,需要求出所有可能的 IP 地址格式。
131. 分割回文串
题目给出一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
306.累加数
累加数是一个字符串,组成它的数字可以形成累加序列。一个有效的累加序列必须至少包含 3 个数。除了最开始的两个数以外,字符串中的其他数都等于它之前两个数相加的和。
这个模板如下:
Class Solution{
//res用来保存最后结果
List res = new ArrayList<>();
//递归函数,list用于保存满足条件的结果,pos用于指示字符的位置,input为输入的字符串
public void helper(List list,int pos,String input){
//当遍历到最后一个字符时,加入结果集
if(pos == intput.length() && 其它的终止条件){
res.add(new ArrayList<>(list));
return;
}
for(int i = 1;i <= 子字符需要的长度;i++){
//剪枝
if (pos+ i > s.length()) break;
//获得子字符串
String subStr = input.subString(pos,pos+i);
//根据题目要求筛选子字符串
子字符串筛选....
//将符合条件的子字符串加入list
list.add(subStr);
helper(list,pos+1,input);
//回退
list.remove(list.size()-1);
}
}
}
93. 复原IP地址
/**
* ip地址每段在0~255之间,且不能以0作为开头,如012,这些可以作为剪枝条件
* 因为每次分割出的自字符串需要用.拼接,所以暂时使用List来储存分段的ip地址,最后再用.拼接即可
*/
class Solution {
List res = new ArrayList<>();
public List restoreIpAddresses(String s) {
if (s.isEmpty()) return res;
helper(s, 0, new ArrayList());
return res;
}
//pos表示当前分割的字符串位置
private void helper(String s, int cur, List list) {
if (list.size() >= 4) {
if(cur == s.length()) res.add(String.join(".", list));
return;
}
for (int i = 1; i <= 3; i++) {
if (cur + i > s.length()) break;
String subStr = s.substring(cur, cur + i);
//判断ip地址是否合适
if ((subStr.startsWith("0") && subStr.length() > 1) || (i == 3 && Integer.valueOf(subStr) > 255))
continue;
list.add(subStr);
helper(s, cur + i, list);
list.remove(list.size() - 1);
}
}
}
131. 分割回文串
/**
* 使用回溯算法。
* 只有一个字符的字符串也是回文串
* 所以设定一个变量cur指代当前递归的字符串位置,如果当前字符是回文串,则加入结果集,如果不是直接continue。
* 当cur==s.length()时表示已找到一个结果,加入结果集
*/
class Solution {
List> res = new ArrayList<>();
public List> partition(String s) {
if (s.isEmpty()) return res;
helper(s, new ArrayList<>(), 0);
return res;
}
private void helper(String s, List list, int cur) {
if (cur == s.length()) {
res.add(new ArrayList<>(list));
return;
}
for (int i = 1; i <= s.length(); i++) {
if (cur + i > s.length()) break;
String subStr = s.substring(cur, cur + i);
if (!isPalindrome(subStr)) continue;
//加入当前回文串
list.add(subStr);
helper(s, list, cur + i);
//回退
list.remove(list.size() - 1);
}
}
private boolean isPalindrome(String subStr) {
if (subStr.length() == 1) return true;
char[] chars = subStr.toCharArray();
for (int i = 0; i < chars.length / 2; i++) {
if (chars[i] != chars[chars.length - i - 1])
return false;
}
return true;
}
}
306. 累加数
class Solution {
boolean flag = false;
public boolean isAdditiveNumber(String num) {
if (num.isEmpty()) return false;
helper(num, 0, new ArrayList<>());
return flag;
}
private void helper(String num, int cur, List list) {
//判断
if (cur == num.length() && list.size() > 2) {
flag = true;
return;
}
for (int i = 1; i <= num.length(); i++) {
if (flag) break;
if (cur + i > num.length()) break;
String subStr = num.substring(cur, cur + i);
//当前数不能以0开头
if (subStr.startsWith("0") && subStr.length() > 1) continue;
//如果结果集已经有两个数,则判断前两个数相加是否为当前数
if (list.size() >= 2) {
if (Long.valueOf(subStr) != Long.valueOf(list.get(list.size() - 1)) + Long.valueOf(list.get(list.size() - 2)))
continue;
}
list.add(subStr);
helper(num, cur + i, list);
list.remove(list.size() - 1);
}
}
}
842. 将数组拆分成斐波那契序列
给定一个数字字符串 S,比如 S = “123456579”,我们可以将它分成斐波那契式的序列 [123, 456, 579]。
形式上,斐波那契式序列是一个非负整数列表 F,且满足:
0 <= F[i] <= 2^31 - 1,(也就是说,每个整数都符合 32 位有符号整数类型);
F.length >= 3;
对于所有的0 <= i < F.length - 2,都有 F[i] + F[i+1] = F[i+2] 成立。
另外,请注意,将字符串拆分成小块时,每个块的数字一定不要以零开头,除非这个块是数字 0 本身。
class Solution {
public List splitIntoFibonacci(String S) {
List res = new ArrayList<>();
helper(S, res, 0);
return res;
}
private boolean helper(String s, List list, int pos) {
//因为斐波拉契数组至少为3个元素,找到后直接返回true
if(pos == s.length() && list.size() > 2){
return true;
}
for (int i = 1; i <= s.length(); i++) {
if (pos + i > s.length()) break;
String subStr = s.substring(pos, pos + i);
//剪枝条件1:数字以0开头
if (subStr.startsWith("0") && subStr.length() > 1) continue;
//剪枝条件2:当前字符串不能超过Integer的最大值
if (Long.valueOf(subStr) > Integer.MAX_VALUE) break;
//剪枝条件3:当前数不等于前两个数之和
if (list.size() >= 2 && Integer.valueOf(subStr) != list.get(list.size() - 1) + list.get(list.size() - 2))
continue;
//将当前值加入结果集
list.add(Integer.valueOf(subStr));
//递归,找到一个结果就返回
if (helper(s, list, pos + i)) return true;
list.remove(list.size() - 1);
}
return false;
}
}