数组
大家好,我是老马。
今天我们一起来学习一下数组这种数据结构。
主要知识
数组需要拆分下面几个部分:
-
理论介绍
-
源码分析
-
数据结构实现?
-
题目练习(按照算法思想分类)
-
梳理对应的 sdk 包
-
应用实战
因为这个是 leetcode 系列,所以重点是 4、5(对4再一次总结)。
为了照顾没有基础的小伙伴,会简单介绍一下1的基础理论。
简单介绍1,重点为4。其他不是本系列的重点。
LC131 分割回文串 palindrome-partitioning
给你一个字符串 s,请你将 s 分割成一些 子串,使每个子串都是 回文串 。
返回 s 所有可能的分割方案。
示例 1:
输入:s = “aab” 输出:[[“a”,”a”,”b”],[“aa”,”b”]] 示例 2:
输入:s = “a” 输出:[[“a”]]
提示:
1 <= s.length <= 16 s 仅由小写英文字母组成
v1-回溯
思路
先不考虑剪枝优化。
1) i 可能开始的位置从 0…n-1
从字符串起点开始,尝试所有可能的切分位置
对每个切分,判断当前子串是否是回文
如果是回文,就继续递归处理剩余子串
如果到达字符串末尾,把当前 path 加入结果
2) 维护回溯路径
用一个 List<String> path
存储当前分割方案
遇到末尾就把 path 拷贝到结果列表
3) 回文判断
每次切分子串前都判断是否是回文
可以用双指针 i、j 从两端向中间判断
或者提前用 DP 预处理回文状态,提高性能
实现
public List<List<String>> partition(String s) {
List<List<String>> res = new ArrayList<>();
List<String> path = new ArrayList<>();
backtrack(s, res, path, 0);
return res;
}
private void backtrack(String s, List<List<String>> res, List<String> path, int start) {
// 达到结尾
if(start == s.length()) {
res.add(new ArrayList<>(path));
return;
}
// 遍历处理
for(int i = start; i < s.length(); i++) {
// 只有在满足是回文,子节点才能继续处理
if(isPalindrome(s, start, i)) {
path.add(s.substring(start, i+1));
backtrack(s, res, path, i+1);
path.remove(path.size()-1);
}
}
}
private boolean isPalindrome(String text, int left, int right) {
while(left < right) {
if(text.charAt(left) != text.charAt(right)) {
return false;
}
left++;
right--;
}
return true;
}
效果
8ms 击败 94.65%