前言

本周是学习java的第四周,本周最大的收获是学习了容器框架和回溯算法

参考教程:

本周学习要点:

1.判断String相等时不要使用==而是用equals。

2.StringBuilder(一般使用)线程不安全,效率高,StringBuffer线程安全,效率低。区别于String是他们是可变字符序列。

3.在循环时字符串的拼接使用.append,否则会产生一大堆的对象占用空间。

4.日期的格式转换:

DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String str = df.format(new Date());
Calendar calendar = new GregorianCalendar;

5.泛型可以理解为数据类型的一个占位符(形式参数),在用到时再传入实际类型

6.容器与数组的对比:数组不够容器灵活,但数组效率比容器高。

7.indexOf和lastIndexOf分别返回元素在列表中的第一个或者倒数第一个的索引

题目

找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。

说明:

所有数字都是正整数。

解集不能包含重复的组合。

示例 1:

输入: k = 3, n = 7

输出: [[1,2,4]]

示例 2:

输入: k = 3, n = 9

输出: [[1,2,6], [1,3,5], [2,3,4]]

思路

因为题目限制只允许含有1-9的正整数,所以只要遍历1-9,然后在回溯函数前加一个判断,只要满足条件就返回,代码如下:

class Solution {
List> com = new ArrayList<>();
public List> combinationSum3(int n, int k) {
traceBack(n,k,0,1,new ArrayList<>());
return com;
}
public void traceBack(int n,int k,int sum,int start,List list){
if (sum==n&&k==0){
com.add(new ArrayList(list));
return;
}
for(int i=start;i<10;i++){
list.add(i);
traceBack(n,k-1,sum+i,i+1,list);
list.remove(list.size()-1);
}
}
}

这里递归的关键是将每一次遍历的数都加入list内,当满足条件时就返回,若不满足则将最后一个元素移除然后进入下一次遍历;回溯的关键是要做到先进后出,所以我移除了列表最后一个元素。

sum的作用是用来计算当前加入list内的元素的总值,而当满足条件时return退出当次递归,避免掉不必要的循环,然后移除list最后一个元素然后加入下一次遍历。

start是用来计算当此递归内的遍历是从哪个数开始,去掉不需要的递归,在回溯中被称作剪枝。