子集
题目
思路
迭代构造子集,遍历数组,每遍历一个元素,将当前所有的子集扩展,形成包含该元素的新子集。
代码
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
res.add(new ArrayList<Integer>());
for(int num : nums){
int size = res.size();
for(int i = 0; i < size; i++){
List<Integer> temp = new ArrayList<Integer>(res.get(i));
temp.add(num);
res.add(temp);
}
}
return res;
}
电话号码的字母
题目
思路
使用递归,排序出每一种可能
代码
List<String> res = new ArrayList<>();
char []a = {'2','3','4','5','6','7','8','9'};
char [][]b={{'a','b','c'},{'d','e','f'},{'g','h','i'},{'j','k','l'},{'m','n','o'},{'p','q','r','s'},{'t','u','v'},{'w','x','y','z'}};
public List<String> letterCombinations(String digits) {
if(digits.isEmpty()){
return res;
}
char[] charArray = digits.toCharArray();
List<char[]> chars = new ArrayList<>();
for(char c:charArray){
for(int i=0;i<a.length;i++){
if(a[i]==c){
chars.add(b[i]);
continue;
}
}
}
for(int i=0;i<chars.get(0).length;i++){
fun(String.valueOf(chars.get(0)[i]),chars,1);
}
return res;
}
private void fun(String s, List<char[]> chars, int x) {
if(x==chars.size()||s.length()==chars.size()){
// System.out.println(s);
res.add(s);
return;
}
for(int i=0;i<chars.get(x).length;i++){
String c = String.valueOf(chars.get(x)[i]);
fun(s+c,chars,x+1);
}
}
组合总数
题目
思路
使用递归模拟所有可能
通过在递归函数 fun2 中,传递当前元素的索引 i,这样可以保证后续递归中只选择当前元素或后续元素,防止选择之前的元素,避免生成重复组合。
回溯时删除最后一个元素恢复状态
代码
List<List<Integer>> ans = new ArrayList<>();
public List<List<Integer>> combinationSum(int[] candidates, int target) {
for(int i=0;i<candidates.length;i++){
List<Integer> list = new ArrayList<>();
list.add(candidates[i]);
fun2(list,target-candidates[i],candidates,i);
}
return ans;
}
private void fun2(List<Integer> list, int t, int[] candidates,int i) {
if(t==0){
List<Integer> in = new ArrayList<>(list);
ans.add(in);
return;
}
for (int j=i;j<candidates.length;j++) {
if (t >= candidates[j]) {
list.add(candidates[j]);
fun2(list, t - candidates[j], candidates,j);
list.removeLast();
}
}
}
括号生成
题目
思路
- 用递归的方式构造每一个有效的括号组合。
- 维护两个变量
left
和right
,分别表示左括号(
和右括号)
的剩余数量。 - 只要左括号还有剩余,递归地尝试添加左括号;只有在右括号数量比左括号多时,才可以添加右括号。
- 当左右括号都用完时,说明生成了一个有效的括号组合,将其加入结果列表。
代码
public List<String> generateParenthesis(int n) {
List<String> sum = new ArrayList<>();
if(n==0){
return sum;
}
fun3(sum,"",n,n);
return sum;
}
private void fun3(List<String> sum, String s, int l, int r) {
if(l==0&&r==0){
sum.add(s);
return;
}
if(l>0){
fun3(sum,s+"(",l-1,r);
}
if(r>l){
fun3(sum,s+")",l,r-1);
}
}
单词搜索
题目
思路
dfs搜索,终止条件就是k==charArr.length
代码
public boolean exist(char[][] board, String word) {
int n = board.length;
int m = board[0].length;
boolean[][] visited = new boolean[n][m];
char[] charArray = word.toCharArray();
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(board[i][j]==charArray[0]){
visited[i][j] = true;
if(fun4(board,i,j,visited,charArray,1)){
return true;
}
visited[i][j] = false;
}
}
}
return false;
}
int[] aa = {0,0,-1,1};
int[] bb = {-1,1,0,0};
private boolean fun4(char[][] board,int x, int y, boolean[][] visited, char[] charArray,int k) {
if(k==charArray.length){
return true;
}
for(int i=0;i<4;i++){
int xx = x+aa[i];
int yy = y+bb[i];
if(xx<visited.length&&xx>=0&&yy<visited[0].length&&yy>=0&&!visited[xx][yy]&&k<charArray.length){
if(board[xx][yy]==charArray[k]){
visited[xx][yy] = true;
if(fun4(board,xx,yy,visited,charArray,k+1)){
return true;
}
visited[xx][yy] = false;
}
}
}
return false;
}