day*
上周摆烂了一周
由于后续需要用到Java 因此从今天开始学习使用Java。
基础语法:
-
Java ArrayList
ArrayList<E> objectName =new ArrayList<>(); // 初始化 //增:add(); //删:remove(); //改:set(2,“wiki”); //查:get();
关于Java中函数参数的问题,由于Java中没有指针的概念,因此所有的参数都是采用值传递。
??? 采用值传递的话,Arrays.sort()是如何进行排序的。
216.组合总和III
如果把 组合问题理解了,本题就容易一些了。
题目链接/文章讲解:programmercarl.com/0216.%E7%BB…
思路: 回溯中一道基本的题,在回溯的过程中,通过遍历数组,如果当前和小于目标值,则需要加入新的值,如果大于则需要回退。采用排序来进行剪枝的操作。
代码:
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(candidates);
backTracking(candidates,new ArrayList<>(),res,target,0 ,0);
return res;
}
public void backTracking(int[] candidates,List<Integer> path,List<List<Integer>> res,int target,int idx,int sum){
if(sum == target){
res.add(new ArrayList<>(path));
return;
}
for(int i = idx;i<candidates.length;i++){
if(sum+candidates[i]>target) break;
path.add(candidates[i]);
backTracking(candidates,path,res,target,i,sum+candidates[i]);
path.remove(path.size()-1);
}
}
}
40.组合总和II
本题开始涉及到一个问题了:去重。
注意题目中给我们 集合是有重复元素的,那么求出来的 组合有可能重复,但题目要求不能有重复组合。
题目链接/文章讲解:programmercarl.com/0040.%E7%BB…
思路: 对于同一层的节点需要进行去重判断,而对于递归向下的则不需要。
代码:
class Solution {
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(candidates);
backTraversing(res,candidates,new ArrayList<>(),target,0,0);
return res;
}
public void backTraversing(List<List<Integer>> res,int[] candidates,List<Integer> path,int target,int idx,int sum){
if(sum==target){
res.add(new ArrayList<>(path)); //与res.add(path)的区别?????
return;
}
for(int i = idx;i<candidates.length;i++){
if(sum>target) break; //剪枝操作,避免超时
if (i > idx && candidates[i] == candidates[i - 1]) { //i=idx刚到这一层
continue;
}
path.add(candidates[i]);
backTraversing(res,candidates,path,target,i+1,sum+candidates[i]); //i+1 避免递归深度中的重复节点
path.remove(path.size()-1);
}
}
}
131.分割回文串
本题较难,大家先看视频来理解 分割问题,明天还会有一道分割问题,先打打基础。
programmercarl.com/0131.%E5%88…
视频讲解:www.bilibili.com/video/BV1c5…
代码:
class Solution {
List<List<String>> lists = new ArrayList<>();
Deque<String> deque = new LinkedList<>();
public List<List<String>> partition(String s) {
backTracking(s, 0);
return lists;
}
private void backTracking(String s, int startIndex) {
//如果起始位置大于s的大小,说明找到了一组分割方案
if (startIndex >= s.length()) {
lists.add(new ArrayList(deque));
return;
}
for (int i = startIndex; i < s.length(); i++) {
//如果是回文子串,则记录
if (isPalindrome(s, startIndex, i)) {
String str = s.substring(startIndex, i + 1);
deque.addLast(str);
} else {
continue;
}
//起始位置后移,保证不重复
backTracking(s, i + 1);
deque.removeLast();
}
}
//判断是否是回文串
private boolean isPalindrome(String s, int startIndex, int end) {
for (int i = startIndex, j = end; i < j; i++, j--) {
if (s.charAt(i) != s.charAt(j)) {
return false;
}
}
return true;
}
}