好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

代码随想录算法训练营第二十五天| 216.组合总和III 17.电话号码的字母组合

 

216.组合总和III 

      卡哥建议: 如果把 组合问题理解了,本题就容易一些了。 

     题目链接/文章讲解:https://programmercarl.com/0216.%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8CIII.html

     视频讲解:https://www.bilibili.com/video/BV1wg411873x

    做题思路:

   本题k相当于树的深度,9(因为整个集合就是9个数)就是树的宽度。

   例如 k = 2,n = 4的话,就是在集合[1,2,3,4,5,6,7,8,9]中求 k(个数) = 2, n(和) = 4的组合。

   选取过程如图:

    图中,可以看出,只有最后取到集合(1,3)和为4 符合条件。

   回溯三部曲看卡哥文章吧。

    剪枝优化:

   1,已选元素总和如果已经大于n(图中数值为4)了,那么往后遍历就没有意义了,直接剪掉。

   2,for循环的范围也可以剪枝,i <= 9 - (k - path.size()) + 1就可以了,和昨天的题一样

    本题代码:

   1   class   Solution {
   2   private  :
   3      vector<vector< int >> result;  //   存放结果集 
  4      vector< int > path;  //   符合条件的结果 
  5       void  backtracking( int  targetSum,  int  k,  int  sum,  int   startIndex) {
   6           if  (sum > targetSum) {  //   剪枝操作 
  7               return ;  //   如果path.size() == k 但sum != targetSum 直接返回 
  8           }
   9           if  (path.size() ==  k) {
  10               if  (sum ==  targetSum) result.push_back(path);
  11               return  ;
  12           }
  13           for  ( int  i = startIndex; i <=  9  - (k - path.size()) +  1 ; i++) {  //   剪枝 
 14              sum += i;  //   处理 
 15              path.push_back(i);  //   处理 
 16              backtracking(targetSum, k, sum, i +  1 );  //   注意i+1调整startIndex 
 17              sum -= i;  //   回溯 
 18              path.pop_back();  //   回溯 
 19           }
  20       }
  21  
 22   public  :
  23      vector<vector< int >> combinationSum3( int  k,  int   n) {
  24          result.clear();  //   可以不加 
 25          path.clear();    //   可以不加 
 26          backtracking(n, k,  0 ,  1  );
  27           return   result;
  28       }
  29  }; 

 

 17.电话号码的字母组合 

      卡哥建议: 本题大家刚开始做会有点难度,先自己思考20min,没思路就直接看题解。 

     题目链接/文章讲解:https://programmercarl.com/0017.%E7%94%B5%E8%AF%9D%E5%8F%B7%E7%A0%81%E7%9A%84%E5%AD%97%E6%AF%8D%E7%BB%84%E5%90%88.html

     视频讲解:https://www.bilibili.com/video/BV1yV4y1V7Ug

    做题思路:

      电话按键上2~9数字上对应着3个或4个字母,题目求的是输入数字,输出字母的组合,可以使用map或者定义一个二维数组,例如:string letterMap[10][],来做映射,10行,4列的二维数组,代码见卡哥文章。

 

      图中可以看出遍历的深度,就是输入"23"的长度,而叶子节点就是我们要收集的结果,输出["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]。

   需要一个字符串s来收集叶子节点的结果,然后用一个字符串数组result保存起来,   

   代码中的 index 是从0开始的,是记录遍历第几个数字了,就是用来遍历digits的(题目中给出数字字符串“23”),就是下标,同时index也表示树的深度。 

   本题代码:

   1   class   Solution {
   2   private  :
   3       const   string  letterMap[ 10 ] =  { //二维数组,10行,列并没有定义,但能看出来
   4           "" ,  //   0 
  5           "" ,  //   1 
  6           "  abc  " ,  //   2 
  7           "  def  " ,  //   3 
  8           "  ghi  " ,  //   4 
  9           "  jkl  " ,  //   5 
 10           "  mno  " ,  //   6 
 11           "  pqrs  " ,  //   7 
 12           "  tuv  " ,  //   8 
 13           "  wxyz  " ,  //   9 
 14       };
  15   public  :
  16      vector< string >  result;//放叶子节点的结果
  17       string   s;
  18       void  backtracking( const   string & digits,  int   index) {
  19           if  (index ==  digits.size()) {
  20               result.push_back(s);
  21               return  ;
  22           }
  23           int  digit = digits[index] -  '  0  ' ;         //   将index指向的数字转为int,比如digits[0]="2",减完后,就是2了 
 24           string  letters = letterMap[digit];       //   取数字对应的字符集,比如,letterMap[2]="abc",然后在二维数组里就能找到对应的字符串 
 25           for  ( int  i =  0 ; i < letters.size(); i++ ) { //树的结构,看上图
  26              s.push_back(letters[i]);             //   处理 
 27              backtracking(digits, index +  1 );     //   递归,注意index+1,一下层要处理下一个数字了 
 28              s.pop_back();                        //   回溯 
 29           }
  30       }
  31      vector< string > letterCombinations( string   digits) {
  32           s.clear();
  33           result.clear();
  34           if  (digits.size() ==  0  ) {
  35               return   result;
  36           }
  37          backtracking(digits,  0  );
  38           return   result;
  39       }
  40  }; 

 

 

 

查看更多关于代码随想录算法训练营第二十五天| 216.组合总和III 17.电话号码的字母组合的详细内容...

  阅读:46次