Day25|组合板子|216. 组合总和 III| 17. 电话号码的字母组合

组合板子+剪枝

  • 216. 组合总和 III
      • 剪枝操作?
      • 17. 电话号码的字母组合

216. 组合总和 III

class Solution {
private:
    vector<int>temp;
    vector<vector<int>>result;
    //sum 存和,index为回溯提供下标
    void backtracking(int k,int n,int sum,int index)
    {
        if(temp.size() == k)//判断一维数组的个数是否等于k
        {
            if(sum == n ) //等于所求值 存入,佛则返回上一层;
            {
                result.push_back(temp);
            }
            return; //如果不符合要求,返回上一层
        }
        for(int i=index;i<=9;i++)//无剪枝版(第一次1~9种情况)
        {
            sum+=i;//和值改变
            temp.push_back(i);//存入i
            backtracking(k,n,sum,i+1);//i+1让范围向后推1 例如2~9
            sum-=i;//回溯过程
            temp.pop_back();
        }
    }
public:
    vector<vector<int>> combinationSum3(int k, int n) {
        backtracking(k,n,0,1);
        return result;
    }
};

剪枝操作?

1.想想如果sum已经超过了,目标值但此时一维数组个数还没有达到k
我们直接return上一层!

2.如果我们不能让一维数组的个数到k,我们是不是直接把这个分支剪掉,避免非必要循环!

例如:我们要求 k=2,但是递归到 9已经没有意义!
k=3,我们递归到7就可以,{7.8.9}后面已经没有必要了去递归了,因为怎么递归都满足不了size=k;
所以怎么递归?
我们把9-(k-size)//假设k=2,第一次size=0所以9-(2-0)=7,我们要递归到8,所以9-(k-size)+1
假设k=3,9-(k-size)+1=7,第一次正好遍历到7
第二次size已经+1,则9-(k-size)+1=8,则8,同理下一次为9,所以遍历为{7,8,9}

class Solution {
private:
    vector<int>temp;
    vector<vector<int>>result;
    //sum 存和,index为回溯提供下标
    void backtracking(int k,int n,int sum,int index)
    {
        if(sum>n) return;
        if(temp.size() == k)//判断一维数组的个数是否等于k
        {
            if(sum == n ) //等于所求值 存入,佛则返回上一层;
            {
                result.push_back(temp);
            }
            return; //如果不符合要求,返回上一层
        }
        for(int i=index;i<=9-(k-temp.size())+1;i++)//无剪枝版(第一次1~9种情况)
        {
            sum+=i;//和值改变
            temp.push_back(i);//存入i
            backtracking(k,n,sum,i+1);//i+1让范围向后推1 例如2~9
            sum-=i;//回溯过程
            temp.pop_back();
        }
    }
public:
    vector<vector<int>> combinationSum3(int k, int n) {
        backtracking(k,n,0,1);
        return result;
    }
};

17. 电话号码的字母组合

class Solution {
private:
        const string keys[10] = {
        "", // 0
        "", // 1
        "abc", // 2
        "def", // 3
        "ghi", // 4
        "jkl", // 5
        "mno", // 6
        "pqrs", // 7
        "tuv", // 8
        "wxyz", // 9
    };
        string s;
        vector<string>result;
        //index 无比重要,它是确定到输入字符串数组遍历到哪里了!
        //"23",index=0,说明是2,index=1,说明是3
        void backtarcking(const string &digits,int index)
        {
            if( index == digits.size())//index在“23”情况不是到1就行了吗?我们在“23”后面进入下一次index已经等于2了,直接return!而且回溯正确
            {result.push_back(s);
            return;
            }
        int stand=digits[index]-'0';//index妙用,stand可以实现9键的按键
        string tempS=keys[stand];//对应按键字符串!
        for(int i=0;i<tempS.size();i++)
        {
            s.push_back(tempS[i]);
            backtarcking(digits,index+1);//index+1,移动到“3”;
            s.pop_back();//回溯
        }
    }
public:
    vector<string> letterCombinations(string digits) {
        if(digits.size()==0)
           return result; 
        backtarcking(digits,0);//index为1
          return result;
    }
};

你可能感兴趣的:(水leetcode,算法,数据结构,leetcode)