随意随想

知其然,知其所以然

0%

LeetCode 131. 分割回文串

给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。

回文串 是正着读和反着读都一样的字符串。

示例 1:
输入:s = “aab”
输出:[[“a”,”a”,”b”],[“aa”,”b”]]

示例 2:
输入:s = “a”
输出:[[“a”]]

提示:
1 <= s.length <= 16
s 仅由小写英文字母组成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
 /**
* 本地是一个回溯题目
* 递归的深度就是s的长度,广度就是从每一层开始切割的位置到s的最右方
*/
public List<List<String>> partition(String s) {
tracking(s, 0);
return rt;
}


public void tracking(String s, int startId) {
if (startId >= s.length()) {
rt.add(new ArrayList<>(item));
}

for (int i = startId; i < s.length(); i++) {
//如果从startId 到 i是回文,那么放到子集
if (huiWen(s, startId, i)) {
item.add(s.substring(startId, i + 1));
} else {
continue;//不是回文串,接续for循环
}
tracking(s, i + 1);//从i+1为其实位置,继续递归下去
item.removeLast();//回溯,需要弹出已经装填的子串(因为该子串已经在数组里面,避免重复所以需要弹出)
}
}

/**
* 判断是否回文使用双指针
* 回文串 是正着读和反着读都一样的字符串。
*/
private boolean huiWen(String s, int start, int end) {
int l = start;
int r = end;
while (l < r) {
if (s.charAt(l) != s.charAt(r)) {
return false;
}
l++;
r--;
}
return true;
}

/**
* 结果集的存放
*/
private List<List<String>> rt = new ArrayList<>();

private LinkedList<String> item = new LinkedList<>();