216.组合总和III

解题思路

代码随想录算法训练营第二十八天 | 216.组合总和III 、17.电话号码的字母组合-LMLPHP 整体的思路和77题是一样的,这里只是多加了个一个和的判断。

剪枝操作也是一样的,首先剪深度,当和已经大于要求的和,那么就不需要继续深入了

第二个是剪宽度,当剩余的元素已经不能满足k个元素了,就不需要继续去拓宽搜索了

class Solution {
private:
    vector<int> path;
    vector<vector<int>> result;
public:
    void backtracking(int k,int n, int startIndex)
    {
        if(n<0) return;    //第一个剪枝,当小于0了,就必须要再继续深入了,因为已经不满足了,剪深度
        if(path.size()>=k)
        {
            if(n==0)
            {
                result.push_back(path);
            }
            return;
        }
        for(int i = startIndex; i<= 9-(k-path.size())+1 ; i++)    //第一个剪枝,剪宽度,和77题一样,还需要k个元素,那么i至多到9-k+1个
        {
              path.push_back(i);
              backtracking(k,n-i,i+1);
              path.pop_back();
        }
    }
    
    vector<vector<int>> combinationSum3(int k, int n) {
              backtracking(k,n,1);
              return result;
    }
};
  • 时间复杂度: O(n * 2^n)
  • 空间复杂度: O(n)

17.电话号码的字母组合

解题思路

这题比较关键的一个点是用二维数组来存储对应关系(这是我没有想到的)

这题回溯的深度,是由元素的个数决定的,这题的宽度,是由对应关系个数确定的。

其次就是注意逻辑的处理即可,详情见代码,本题也不需要剪枝,因为就是需要所有的可能性。

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

class Solution {
private:
    vector<string> result;   //记录结果
    string s;     //记录路径
    const string letterMap[10] = 
    {
        "",
        "",
        "abc",
        "def",
        "ghi",
        "jkl",
        "mno",
        "pqrs",
        "tuv",
        "wxyz",
    };
public:
    void backtracking(const string& digits,int index)   //这里的两个参数分别是题目给的字符串和 当前使用的字符串的下标
    {
        if(index == digits.size())  //当下标越界后就返回
        {
            //在此时收获结果
            result.push_back(s);
            return;
        }
        //取数字,这里使用字符相减即可
        int digit = digits[index] - '0';
        string letter = letterMap[digit];
        for(int i =0;i<letter.size();i++)
        {
             s.push_back(letter[i]);
             backtracking(digits,index+1);  //深入去处理第二个数字
             s.pop_back();     //回溯
        }
    }
    
    vector<string> letterCombinations(string digits) {
        if(digits == "")  return result;
        backtracking(digits,0);
        return result;
    }
};

小知识:string中取出单个的,是字符

const string& 是const引用传递,不会产生副本,也不会改变原来参数的值

&引用传递不会产生副本,直接会修改原来参数的值,传入的是地址

值传递,会产生副本,不会修改原来参数的值

收获

对于回溯里面的具体逻辑处理还是有点不太会,继续加油。 

05-15 09:47