代码随想录【Day 25】 | 216.组合总和III、17.电话号码的字母组合
216.组合总和III
题目链接:216.组合总和III
卡尔文解
视频讲解
解题思路及注意事项:
本题就是在[1,2,3,4,5,6,7,8,9]这个集合中找到和为n的k个数的组合。
相对于77. 组合 (opens new window),无非就是多了一个限制,本题是要找到和为n的k个数的组合,而整个集合已经是固定的了[1,…,9]。
想到这一点了,做过77. 组合 (opens new window)之后,本题是简单一些了。
本题k相当于树的深度,9(因为整个集合就是9个数)就是树的宽度。
例如 k = 2,n = 4的话,就是在集合[1,2,3,4,5,6,7,8,9]中求 k(个数) = 2, n(和) = 4的组合。
选取过程如图:
图中,可以看出,只有最后取到集合(1,3)和为4 符合条件。
代码实现:
class Solution {
private:
vector<int> path;
vector<vector<int>> result;
int cur_sum = 0;
void back_tracking( int k, int target_sum, int start_idx ){
if( path.size() > k ){
return;
}
if(( target_sum == cur_sum ) && path.size() == k ){
result.push_back( path );
return;
}
for ( int i = start_idx; i <= 9; i++ ){
path.push_back( i );
cur_sum += i;
back_tracking( k, target_sum, i + 1 );
cur_sum -= i;
path.pop_back();
}
}
public:
vector<vector<int>> combinationSum3(int k, int n) {
back_tracking( k, n, 1 );
return result;
}
};
17.电话号码的字母组合
题目链接:17.电话号码的字母组合
卡尔文解
视频讲解
解题思路及注意事项:
从示例上来说,输入"23",最直接的想法就是两层for循环遍历了吧,正好把组合的情况都输出了。
如果输入"233"呢,那么就三层for循环,如果"2333"呢,就四层for循环…
大家应该感觉出和77.组合 (opens new window)遇到的一样的问题,就是这for循环的层数如何写出来,此时又是回溯法登场的时候了。
理解本题后,要解决如下三个问题:
数字和字母如何映射
两个字母就两个for循环,三个字符我就三个for循环,以此类推,然后发现代码根本写不出来
输入1 * #按键等等异常情况
#数字和字母如何映射
可以使用map或者定义一个二维数组,例如:string letterMap[10],来做映射,我这里定义一个二维数组,代码如下:
回溯法来解决n个for循环的问题
对于回溯法还不了解的同学看这篇:关于回溯算法,你该了解这些!(opens new window)
例如:输入:“23”,抽象为树形结构,如图所示:
图中可以看出遍历的深度,就是输入"23"的长度,而叶子节点就是我们要收集的结果,输出[“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”]。
代码实现:
class Solution {
string path;
vector<string> result;
string key_string_map[ 10 ] = {
"", "", "abc",
"def", "ghi", "jkl",
"mno", "pqrs", "tuv",
"wxyz"
};
void back_tracking( string digits, int idx ){
if( idx == digits.size()){
result.push_back( path );
return;
}
int i = digits[ idx ] - '0';
string letters = key_string_map[ i ];
for( int i = 0; i < letters.size(); i++ ){
path.push_back( letters[ i ]);
back_tracking( digits, idx + 1 );
path.pop_back();
}
}
public:
vector<string> letterCombinations(string digits) {
if( digits.empty() ) return {};
back_tracking( digits, 0 );
return result;
}
};