打卡第23天------回溯算法

39. 组合总和

本题是 集合里元素可以用无数次,那么和组合问题的差别 其实仅在于 startIndex上的控制

题目链接/文章讲解:代码随想录

视频讲解:带你学透回溯算法-组合总和(对应「leetcode」力扣题目:39.组合总和)| 回溯法精讲!_哔哩哔哩_bilibili

根据卡尔的官方视频讲解,来看一下JS代码吧:

/**
 * @param {number[]} candidates
 * @param {number} target
 * @return {number[][]}
 */
//  回溯三部曲:
// 1、函数参数和返回值
// 2、确定终止条件
// 3、单层搜索逻辑
var combinationSum = function(candidates, target) {
    // 二维数组,存放结果集
    let result = [];
    // 一维数组
    let path = [];
    // path这个数组里面元素的和 = sum
    const backtracking = (candidates, target, sum, startIndex) => {
        if (sum > target) {
            return;
        };
        if (sum == target) {
            result.push(path.slice())
            return;
        }
        for (let i = startIndex;i < candidates.length;i++) {
            path.push(candidates[i]);
            sum += candidates[i];
            // 元素可以重复使用,要保证传进来的为i
            backtracking(candidates, target, sum, i);
            sum -= candidates[i];
            path.pop();
        }
    }
    backtracking(candidates, target, 0, 0)

    return result;
};

40.组合总和II

本题开始涉及到一个问题了:去重。

注意题目中给我们 集合是有重复元素的,那么求出来的 组合有可能重复,但题目要求不能有重复组合。

题目链接/文章讲解:代码随想录

视频讲解:回溯算法中的去重,树层去重树枝去重,你弄清楚了没?| LeetCode:40.组合总和II_哔哩哔哩_bilibili

/**
 * @param {number[]} candidates
 * @param {number} target
 * @return {number[][]}
 */
var combinationSum2 = function(candidates, target) {
    let res = [];
    let path = [];
    let total = 0;
    const len = candidates.length;
    candidates.sort((a, b) => a - b);
    let used = new Array(len).fill(false);
    const backtracking = (startIndex) => {
        if (total === target) {
            res.push([...path]);
            return;
        }
        for(let i = startIndex; i < len && total < target; i++) {
            const cur = candidates[i];
            if (cur > target - total || (i > 0 && cur === candidates[i - 1] && !used[i - 1])) continue;
            path.push(cur);
            total += cur;
            used[i] = true;
            backtracking(i + 1);
            path.pop();
            total -= cur;
            used[i] = false;
        }
    }
    backtracking(0);
    return res;
};

131.分割回文串

本题较难,大家先看视频来理解 分割问题,明天还会有一道分割问题,先打打基础。

代码随想录

视频讲解:带你学透回溯算法-分割回文串(对应力扣题目:131.分割回文串)| 回溯法精讲!_哔哩哔哩_bilibili

看了卡尔的官方视频讲解,看一下JS代码吧:

/**
 * @param {string} s
 * @return {string[][]}
 */
// 一个函数,判断是否是回文串,给定一个字符串判断从start到end的区间是否是回文串
const isPalindrome = (s, l, r) => {
    for (let i = l, j = r; i < j; i++, j--) {
        if(s[i] !== s[j]) return false;
    }
    return true;
}
var partition = function(s) {
    // 一维数组
    let path = [];
    // 二维数组
    let result = [];
    const backtracking = (s, startIndex) => {
        // 确定终止条件
        if (startIndex >= s.length) {
            result.push(path.slice())
            return;
        };
        for (let i = startIndex;i< s.length;i++) {
            // 判断是否是回文串
            if (!isPalindrome(s, startIndex, i)) {
                continue;
            };
            path.push(s.slice(startIndex, i + 1));
            backtracking(s, i + 1);
            path.pop();
        }
    }
    backtracking(s, 0)
    
    return result;
};

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值