代码随想录算法训练营第二十一天 | leetcode:组合总和III,电话号码的字母组合

216. 组合总和 III#

注意的地方#

与昨天的 《77. 组合》 问题不同,不能包含相同的组合两次,这题需要注意去重。

解题方法#

题目固定的数字范围为 1-9,在《77. 组合》即解题基础上,需要处理 path 的累加比较,加入目标数组 res 时,当前 path 是否存在 res 中。

复杂度#

时间复杂度

O(n * 2^n)

空间复杂度

O(n)

code#

class Solution {

    private $res = [];
    private $path = [];
    private $max = 9;
    /**
     * @param Integer $k
     * @param Integer $n
     * @return Integer[][]
     */
    function combinationSum3($k, $n) {
        $this->backtracking($k, $n, 1);
        return $this->res;
    }

    function backtracking($k, $n, $starIndex){
        //print_r($this->path);
        //判断元素个数是否==k && 数组相加==n && 是否存在结果数组
        if(count($this->path) == $k && array_sum($this->path) == $n && !in_array($this->path, $this->res)){
            //先排序,然后放进结果数组,方便后面查重
            sort($this->path);
            $this->res[] = $this->path;
        }
        for($i = $starIndex; $i <= $this->max; $i++){
            $this->path[] = $i;
            $this->backtracking($k, $n, $i+1);
            array_pop($this->path);
        }
    }
}

17. 电话号码的字母组合#

注意的地方#

与之前的组合问题 《77. 组合》 《216. 组合总和 III》 不同,之前的回溯算法求组合都是一个集合里面求组合,这道题是两个集合里面求集合。单靠想象有点难理解,此时一定要画图,有助于理解什么是外层横向 for 循环和纵向递归。

解题方法#

  1. 使用 map 做好数字与字母的映射
  2. 组合长度 k 始终等于输入 digits 的长度
  3. 根据图示不难看出,横向 for 循环为第一个数字指定的字母,纵向是第一个数字指定的字母依次与后续数字字母的组合。
    代码随想录算法训练营第二十一天 | leetcode:组合总和III,电话号码的字母组合

复杂度#

时间复杂度

O(3^m * 4^n)
其中 m 是对应四个字母的数字个数,n 是对应三个字母的数字个数

空间复杂度

O(3^m * 4^n)

code#

class Solution {
    private $relate = [
        '','','abc','def','ghi','jkl','mno','pqrs','tuv','wxyz'
    ];
    private $res = [];
    private $path = [];

    /**
     * @param String $digits
     * @return String[]
     */
    function letterCombinations($digits) {
        if(strlen($digits) == 0) return $this->res;
        $this->backtracking($digits,0);
        return $this->res;
    }
    //index 是digits的下标
    function backtracking($digits,$index){
        //当index = strlen($digits)时 代表遍历完了
        if($index == strlen($digits)){
            $this->res[] = implode("",$this->path);
            return;
        }
        $number = $digits[$index];
        $letter = $this->relate[$number];
        for($i = 0; $i < strlen($letter); $i++){
            $this->path[] = $letter[$i];
            $this->backtracking($digits, $index+1);
            array_pop($this->path);
        }
    }
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。