zoukankan      html  css  js  c++  java
  • [LeetCode题解]216. 组合总和 III

    前言

    看完这篇题解,可以再看看这几个问题:

    题目描述

    216. 组合总和 III

    题目:216. 组合总和 III

    解题思路

    本题与 39. 组合总和40. 组合总和 II 类似,解法一样,主要区别在于剪枝或去重的条件上。

    [39. 组合总和]

    剪枝:target-candidates[i] < 0 表示结果集加上 candidates[i] 将超过 target,不符合条件,剪掉。

    [40. 组合总和 II]

    剪枝条件与上一题一样,主要是去重的条件:i > start && candidates[i] == candidates[i-1]

    [216. 组合总和 III]

    剪枝条件有两个情况,一种跟上两题相同:n - i < 0 ;另一种是:k == 1 && n-i > 0

    算法步骤:

    1. 排序。方便进行剪枝判断。
    2. 回溯。排列、组合类题目常用方法。
    3. 剪枝。提前去掉不符合的结果,降低时间复杂度。
    4. 去重。

    代码实现

    var ans [][]int // 结果集
    var list []int // 临时结果集
    
    func combinationSum3(k int, n int) [][]int {
        /*  
            回溯 + 剪枝 + 去重
            剪枝条件: > k 去掉
            去重条件: 加 start 控制
        */
        ans = make([][]int, 0)
        list = make([]int, 0)
        backtarck(k, n, 1)
        return ans
    }
    
    func backtarck(k int, n int, start int) {
        if n == 0 && k == 0 {
            tmp := make([]int, len(list))
            copy(tmp, list)
            ans = append(ans, tmp)
            return
        }
    
        for i:=start;i<=9;i++ {
            if n - i < 0 {
                break
            }
            if k == 1 && n-i > 0 {
                continue
            }
            list = append(list, i)
            backtarck(k-1, n-i, i+1)
            list = list[:len(list)-1]
        }
    }
    

    复杂度分析:

    • 时间复杂度:(O(2^n * n))。一般的递归树的时间复杂度是 (O(2^n)),遍历 n 的时间复杂度是 (O(n)) ,最终时间复杂度为 (O(2^n * n))
    • 空间复杂度:(O(n))。除了保存结果的数组外,还需要一个数组保存回溯过程的中间结果。
  • 相关阅读:
    Asp.Net Mvc Filter
    使用 EntityFramework后把一个对象序列化成json字符串引起循环引用的问题
    RCTF2020 calc & EasyBlog & swoole
    GKCTF-EzWeb+redis未授权访问
    BJD3rd
    http走私
    网鼎杯2020青龙组 web writeup
    De1CTF 2020 部分web
    js相关trick总结
    xss常见编码解析
  • 原文地址:https://www.cnblogs.com/liang24/p/13652752.html
Copyright © 2011-2022 走看看