Day25:回溯法 LeedCode216.组合总和III 17.电话号码的字母组合

本文主要是介绍Day25:回溯法 LeedCode216.组合总和III 17.电话号码的字母组合,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

216. 组合总和 III

找出所有相加之和为 n 的 k 个数的组合,且满足下列条件:

  • 只使用数字1到9
  • 每个数字 最多使用一次 

返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。

示例 1:

输入: k = 3, n = 7
输出: [[1,2,4]]
解释:
1 + 2 + 4 = 7
没有其他符合的组合了。

思路:本题与77.组合思路一致,无非就是多了一个和的限制

递归三部曲:

1.确定返回值和参数的类型

用全局变量List<List<Integer>> result 和List<Integer> path记录路径和结果,无需返回值,需要传入k(树的深度/数的目标个数),targetSum(目标和),startIndex(为下一层for循环搜索的起始位置),sum(当前和)

 void backtracking(int targetSum,int sum,int k,int startIndex)

2.确定结束条件

遍历到path.size()==k时,判断该路径是否加入结果,结束递归

 if(path.size()==k){
        if(targetSum==sum)
        result.add(new ArrayList(path));
        return;
    }

3.单层递归逻辑

for循环横向遍历,递归纵向遍历,本题和77.组合区别之一就是集合固定的就是9个数[1,...,9],所以for循环固定i<=9,处理过程就是 path收集每次选取的元素

for(int i=startIndex;i<10;i++){
    sum+=i;
    path.add(i);
    backtracking(targetSum,sum,k,i+1);
    sum-=i;
    path.removeLast();

代码参考:

class Solution {List<List<Integer>> result;List<Integer> path;public List<List<Integer>> combinationSum3(int k, int n) {path=new LinkedList<>();result=new ArrayList<>();backtracking(n,0,k,1);return  result;}void backtracking(int targetSum,int sum,int k,int startIndex){if(path.size()==k){if(targetSum==sum)result.add(new ArrayList(path));return;}for(int i=startIndex;i<10;i++){sum+=i;path.add(i);backtracking(targetSum,sum,k,i+1);sum-=i;path.removeLast();}}
}

代码优化:

剪枝:

当剩下的数的个数不够用时path.size()+9-i+1<k时结束递归

当sum>targetSum时结束递归

class Solution {List<List<Integer>> result;List<Integer> path;public List<List<Integer>> combinationSum3(int k, int n) {path=new LinkedList<>();result=new ArrayList<>();backtracking(n,0,k,1);return  result;}void backtracking(int targetSum,int sum,int k,int startIndex){if(targetSum<sum) return;//剪枝if(path.size()==k){if(targetSum==sum)result.add(new ArrayList(path));return;}
//剪枝for(int i=startIndex;i<=path.size()+9-k+1;i++){sum+=i;path.add(i);backtracking(targetSum,sum,k,i+1);sum-=i;path.removeLast();}}
}

17. 电话号码的字母组合

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

示例 1:

输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]

思路:本题要思考几个问题

1.如何将字母和数字对应

用一个字符数组存储每个数字对应的字符串

 numToString=new String[]{"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};

将数字转为对应的字符串
String str=numToString[digits.charAt(index)-'0'];

2.两个数字需要两层循环,三个数字三层循环,如何根据个数实现几层循环

用回溯法,根据是否遍历完digits的每个数字决定是否进行for循环    
     if(digits.length()==index){
    result.add(temp.toString());
    return;

递归三部曲:

1.确定返回值和参数类型

无需返回值,用全局变量List<String> result记录结果 ,传入digits(数字字符串)和index(表示这层循环从哪个数字开始)

全局遍量 String[] numToString记录数字和字符串的对应关系

2.确定递归结束条件

当index==digits.length时结束递归,

如果digits为null或者空串时,返回空List<String> result

 if(digits==null||digits.length()==0){
            return ;
        }

3.确定单层逻辑

首先要取index指向的数字,并找到对应的字符集(手机键盘的字符集)。

然后for循环来处理这个字符集,代码如下:

    //将数字转为对应的字符串
     String str=numToString[digits.charAt(index)-'0'];
     //遍历字符串
     for(int i=0;i<str.length();i++){
        //将字符加入
     temp.append(str.charAt(i));
     //回溯
     backtracking(digits,index+1);
     temp.deleteCharAt(temp.length() - 1);
     }

代码参考:

class Solution {List<String>result;String[] numToString;StringBuilder temp=new StringBuilder();public List<String> letterCombinations(String digits) {numToString=new String[]{"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};result=new ArrayList<>();backtracking(digits,0);return result;}void backtracking(String digits,int index){if(digits==null||digits.length()==0){return ;}//遍历完digits的每个数字,结束递归if(digits.length()==index){result.add(temp.toString());return;}//将数字转为对应的字符串String str=numToString[digits.charAt(index)-'0'];//遍历字符串for(int i=0;i<str.length();i++){//将字符加入temp.append(str.charAt(i));//回溯backtracking(digits,index+1);temp.deleteCharAt(temp.length() - 1);}}
}

 

 

    

 

 

 

这篇关于Day25:回溯法 LeedCode216.组合总和III 17.电话号码的字母组合的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/867728

相关文章

hdu4869(逆元+求组合数)

//输入n,m,n表示翻牌的次数,m表示牌的数目,求经过n次操作后共有几种状态#include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdlib.h>#includ

Go组合

摘要 golang并非完全面向对象的程序语言,为了实现面向对象的继承这一神奇的功能,golang允许struct间使用匿名引入的方式实现对象属性方法的组合 组合使用注意项 使用匿名引入的方式来组合其他struct 默认优先调用外层方法 可以指定匿名struct以调用内层方法 代码 package mainimport ("fmt")type People struct{}type Pe

回溯——9.全排列

力扣题目链接 给定一个 没有重复 数字的序列,返回其所有可能的全排列。 示例: 输入: [1,2,3]输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ] 解题思路 问题建模:题目要求给出一个数组的所有排列组合,属于典型的全排列问题,这可以用回溯法来解决。回溯法通过递归的方式,依次将数组中的每个元素放入排列中,直到生成

17 通过ref代替DOM用来获取元素和组件的引用

重点 ref :官网给出的解释是: ref: 用于注册对元素或子组件的引用。引用将在父组件的$refs 对象下注册。如果在普通DOM元素上使用,则引用将是该元素;如果在子组件上使用,则引用将是组件实例: <!-- vm.$refs.p will be the DOM node --><p ref="p">hello</p><!-- vm.$refs.child will be the c

react笔记 8-17 属性绑定 class绑定 引入图片 循环遍历

1、绑定属性 constructor(){super()this.state={name:"张三",title:'我是一个title'}}render() {return (<div><div>aaaaaaa{this.state.name}<div title={this.state.title}>我是一个title</div></div></div>)} 绑定属性直接使用花括号{}   注

组合c(m,n)的计算方法

问题:求解组合数C(n,m),即从n个相同物品中取出m个的方案数,由于结果可能非常大,对结果模10007即可。       共四种方案。ps:注意使用限制。 方案1: 暴力求解,C(n,m)=n*(n-1)*...*(n-m+1)/m!,n<=15 ; int Combination(int n, int m) { const int M = 10007; int

代码随想录训练营day37|52. 携带研究材料,518.零钱兑换II,377. 组合总和 Ⅳ,70. 爬楼梯

52. 携带研究材料 这是一个完全背包问题,就是每个物品可以无限放。 在一维滚动数组的时候规定了遍历顺序是要从后往前的,就是因为不能多次放物体。 所以这里能多次放物体只需要把遍历顺序改改就好了 # include<iostream># include<vector>using namespace std;int main(){int n,m;cin>>n>>m;std::vector<i

代码随想录打卡Day25

今天一整天都在教研室做实验,没时间刷题,就做了一题,剩下的明天补 491.递增子序列 这道题目和之前的子集问题很像,但是有一点要注意的,这个输入的数组不能进行排序,所以就不能沿用之前的去重逻辑,这道题要去重还是得借助额外的变量来维护元素使用情况,但是这题的used为集合,且不能为全局变量,只能为树层遍历前定义的一个局部变量,除了这个改动以外,其他地方都是高度相似的。 class Soluti

INDEX+SMALL+IF+ROW函数组合使用解…

很多人在Excel中用函数公式做查询的时候,都必然会遇到的一个大问题,那就是一对多的查找/查询公式应该怎么写?大多数人都是从VLOOKUP、INDEX+MATCH中入门的,纵然你把全部的多条件查找方法都学会了而且运用娴熟,如VLOOKUP和&、SUMPRODUCT、LOOKUP(1,0/....,但仍然只能对这种一对多的查询望洋兴叹。   这里讲的INDEX+SMALL+IF+ROW的函数组合,

风控系统之指标回溯,历史数据重跑

个人博客:无奈何杨(wnhyang) 个人语雀:wnhyang 共享语雀:在线知识共享 Github:wnhyang - Overview 回顾 默认你已经看过之前那篇风控系统指标计算/特征提取分析与实现01,Redis、Zset、模版方法。 其中已经介绍了如何利用redis的zset结构完成指标计算,为了方便这篇文章的介绍,还是在正式开始本篇之前回顾一下。 时间窗口 zset