一个月速刷leetcodeHOT100 day15 彻底搞懂回溯算法 以及相关题目

news2024/11/16 5:47:40

回溯算法采用试错的思想,它尝试分步的去解决一个问题。在分步解决问题的过程中,当它通过尝试发现现有的分步答案不能得到有效的正确的解答的时候,它将取消上一步甚至是上几步的计算,再通过其它的可能的分步解答再次尝试寻找问题的答案

全排列

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

示例 1:

**输入:**nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

示例 2:

**输入:**nums = [0,1]
输出:[[0,1],[1,0]]

示例 3:

**输入:**nums = [1]
输出:[[1]]

const permute = (nums) => {
// 1. 设置结果集

const result = [];

// 2. 回溯

const recursion = (path, set) => {

// 2.1 设置回溯终止条件

if (path.length === nums.length) {

// 2.1.1 推入结果集

result.push(path.concat());

// 2.1.2 终止递归

return;

}

// 2.2 遍历数组

for (let i = 0; i < nums.length; i++) {

// 2.2.1 必须是不存在 set 中的坐标

if (!set.has(i)) {

// 2.2.2 本地递归条件(用完记得删除)

path.push(nums[i]);

set.add(i);

// 2.2.3 进一步递归

recursion(path, set);

// 2.2.4 回溯:撤回 2.2.2 的操作

path.pop();

set.delete(i);

}

}

};

recursion([], new Set());

// 3. 返回结果

return result;

};

子集

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的
子集
(幂集)。
解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
示例 1:
**输入:**nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]

示例 2:

**输入:**nums = [0]
输出:[[],[0]]

var letterCombinations = (digits) => {

if (digits.length == 0) return [];

const res = [];

const map = {//建立电话号码和字母的映射关系

2: "abc",

3: "def",

4: "ghi",

5: "jkl",

6: "mno",

7: "pqrs",

8: "tuv",

9: "wxyz",

};

  

const dfs = (curStr, i) => {//curStr是递归每一层的字符串,i是扫描的指针

if (i > digits.length - 1) {//边界条件,递归的出口

res.push(curStr); //其中一个分支的解推入res

return; //结束递归分支,进入另一个分支

}

const letters = map[digits[i]]; //取出数字对应的字母

for (const l of letters) {

//进入不同字母的分支

dfs(curStr + l, i + 1); //参数传入新的字符串,i右移,继续递归

}

};

dfs("", 0); // 递归入口,传入空字符串,i初始为0的位置

return res;

};

数组总和

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。

对于给定的输入,保证和为 target 的不同组合数少于 150 个。

示例 1:

**输入:**candidates = [2,3,6,7], target = 7
输出:[[2,2,3],[7]]
解释:
2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。
7 也是一个候选, 7 = 7 。
仅有这两种组合。

示例 2:

输入: candidates = [2,3,5], target = 8
输出: [[2,2,2,2],[2,3,3],[3,5]]

示例 3:

输入: candidates = [2], target = 1
输出: []

var combinationSum = function(candidates, target) {

// 先队候选数字排序

candidates = candidates.sort((a,b)=>a-b);

const result = []; // 存储最后返回的结果

const path = []; // 路径

// sum 为当前路径上的所有元素之和

function backTrack(startIndex,sum) {

// 判断 和 是否与target相等

if( sum === target) {

result.push([...path]);

}

for(let i = startIndex; i < candidates.length; i++){

// 剪枝

if(candidates[i]+sum > target) return;

path.push(candidates[i]);

// candidates[i]表示候选数组中第i个元素的值

backTrack(i, sum + candidates[i]);

path.pop();

}

}

backTrack(0 , 0);

return result;

};

括号生成

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

示例 1:

**输入:**n = 3
输出:[“((()))”,“(()())”,“(())()”,“()(())”,“()()()”]

示例 2:

**输入:**n = 1
输出:[“()”]

var generateParenthesis = function(n) {

const res = []; // 输出的结果数组

const generate = (str, left, right) => {

if (str.length == 2 * n) { // 字符串构建完成

res.push(str); // 将字符串加入res

return; // 结束当前递归(结束当前搜索分支)

}

if (left > 0) { // 只要左括号有剩,可以选它,继续递归做选择

generate(str + '(', left - 1, right);

}

if (right > left) { // 右括号的保有数量大于左括号的保有数量,才能选右括号

generate(str + ')', left, right - 1);

}

};
  
generate('', n, n); // 递归的入口,初始字符串是空字符串,初始括号数量都是n

return res;


};

单词搜索

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

示例 1:

**输入:**board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCCED”
**输出:**true

示例 2:

**输入:**board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “SEE”
**输出:**true

示例 3:

**输入:**board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCB”
**输出:**false

var exist = function (board, word) {

let m = board.length;

let n = board[0].length;

//越界处理

// board[-1] = []; // 这里处理比较比较巧妙,利用了js的特性

// board.push([]);

  

//寻找首个字母

for (let x = 0; x < m; x++) {

for (let y = 0; y < n; y++) {

if (word[0] === board[x][y]) {

if (dfs(word, board, x, y, 0)) {

return true;

}

}

}

}

return false;

};

let dfs = function (word, board, x, y, index) {

let m = board.length;

let n = board[0].length;

if (index + 1 === word.length) return true;

  

var tmp = board[x][y];

// 标记该元素已使用

board[x][y] = false

if (y+1 < n && board[x][y + 1] === word[index + 1] && dfs(word, board, x, y + 1, index + 1)) return true;

if (y - 1 >= 0 && board[x][y - 1] === word[index + 1] && dfs(word, board, x, y - 1, index + 1)) return true;

if (x + 1 < m && board[x + 1][y] === word[index + 1] && dfs(word, board, x + 1, y, index + 1)) return true;

if (x - 1 >= 0 && board[x - 1][y] === word[index + 1] && dfs(word, board, x - 1, y, index + 1)) return true;

// 回溯

board[x][y] = tmp;

}

分割回文串

给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是

回文串

。返回 s 所有可能的分割方案。

示例 1:

**输入:**s = “aab”
输出:[[“a”,“a”,“b”],[“aa”,“b”]]

示例 2:

**输入:**s = “a”
输出:[[“a”]]

var partition = function(s) {
    //判断回文
    const isPal = function(s, l ,r) {
        while(l < r) {
            if(s[l] !== s[r]) {
                return false;
            }
            l++;
            r--;
        }
        return true;
    }
    let res = [];
    let path = [];
    const bt = function(startIndex) {
        //如果已经切割到最后就结束
        if(startIndex === s.length) {
            res.push([...path]);
            return;
        } 
        for(let i = startIndex; i < s.length; i++) {
            // 是回文子串
            if(isPal(s, startIndex, i)) {
                path.push(s.slice(startIndex, i + 1));  //slice是右开,所以得加1
                bt(i + 1);  
                path.pop(); //回溯
            } else {
                continue;
            }
        }
    }
    bt(0);
    return res;
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1800384.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何在MySQL中实现upsert:如果不存在则插入?

目录 1 使用 REPLACE 2 使用 INSERT ... ON DUPLICATE KEY UPDATE 使用 INSERT IGNORE 有效会导致 MySQL 在尝试执行语句时忽略执行错误 INSERT 。这意味着 包含 索引或 字段 INSERT IGNORE 中重复值的语句 不会 产生错误&#xff0c;而只是完全忽略该特定 命令。其明显目的是…

vue2使用antv/g6-editor实现可拖拽流程图

依赖下载 照着这个引入就好&#xff0c;然后npm install 源码 <template><div id"vue-g6-editor"><el-row><el-col :span"24"></el-col></el-row><!-- 工具栏 --><el-row><el-col :span"24&qu…

移动端 UI 风格,打造极致体验

移动端 UI 风格&#xff0c;打造极致体验

Three.js和Babylon.js,webGL中的对比效果分析!

hello&#xff0c;今天分享一些three.js和babylon.js常识&#xff0c;为大家选择three.js还是babylon.js做个分析&#xff0c;欢迎点赞评论转发。 一、Babylon.js是什么 Babylon.js是一个基于WebGL技术的开源3D游戏引擎和渲染引擎。它提供了一套简单易用的API&#xff0c;使开发…

在Windows上用Llama Factory微调Llama 3的基本操作

这篇博客参考了一些文章&#xff0c;例如&#xff1a;教程&#xff1a;利用LLaMA_Factory微调llama3:8b大模型_llama3模型微调保存-CSDN博客 也可以参考Llama Factory的Readme&#xff1a;GitHub - hiyouga/LLaMA-Factory: Unify Efficient Fine-Tuning of 100 LLMsUnify Effi…

【数据结构】平衡二叉树左旋右旋与红黑树

平衡二叉树左旋右旋与红黑树 平衡二叉树 定义 平衡二叉树是二叉搜索树的一种特殊形式。二叉搜索树&#xff08;Binary Search Tree&#xff0c;BST&#xff09;是一种具有以下性质的二叉树&#xff1a; 对于树中的每个节点&#xff0c;其左子树中的所有节点都小于该节点的值…

创意KMS知识图谱ui设计合集来了

创意KMS知识图谱ui设计合集来了

解决nvidia驱动和CUDA升级问题

解决nvidia驱动和CUDA升级问题 注释&#xff1a;升级高版本的nvidia驱动和cuda是不影响现有的docker镜像和容器的。因为是向下兼容的。仅仅升级后重启服务器即可。 ERROR: An NVIDIA kernel module ‘nvidia-drm’ appears to already be loaded in your kernel. This may be…

微信公众号二维码登录

微信扫码登录&#xff1a; 方式1、微信开放平台&#xff1a;第三方应用接入&#xff0c;依赖公司在【微信开放平台】用【公司营业执照】注册的账号&#xff0c;才能实现扫码登录 微信开放平台 方式2、微信公众平台&#xff1a;扫码通过微信公众号授权登录的&#xff0c;借助个人…

【vscode,gdb】在vscode调试时显示STL容器内容(开启gdb的pretty-printing)

在gdb调试cpp代码时&#xff0c;会发现它无法打印stl库中的容器&#xff0c;所以需要利用pretty-printing来将它打印出来 配置方法 在home下新建文件夹.gdb&#xff0c;然后在.gdb下新建文件printers.py 进入网址https://gcc.gnu.org/git/?pgcc.git;ablob_plain;flibstdc%2…

Mamba v2诞生:2 那些烧脑的矩阵们

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调或者LLM背后的基础模型新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;则提…

用自然语言连接信息孤岛

信息孤岛互联互通的困难 尽管已经进入了互联网时代&#xff0c;信息系统中的信息孤岛现象仍然十分地严重&#xff0c;不同部门&#xff0c;不同机器之间难以实现信息的互联互通。存在大量的信息孤岛。 不同信息系统的相互通信依赖通信协议和数据模型的定义&#xff0c;前者决定…

南卡、漫步者和Cleer该怎么选?高性价比耳机推荐!

身为一位拥有五年资历的数码产品评测专家&#xff0c;我亲身体验了各类蓝牙耳机&#xff0c;足迹遍及小众新秀至国际知名品牌。频繁受邀于不同厂商&#xff0c;为他们的新品提供专业见解&#xff0c;同时&#xff0c;我的社交平台私信中也满载着粉丝关于开放式耳机选择的热切询…

乡村振兴的乡村旅游品质提升:提升乡村旅游服务质量,打造乡村旅游品牌,增强乡村旅游吸引力,打造具有旅游特色的美丽乡村

目录 一、引言 二、提升乡村旅游服务质量 1、完善基础设施建设 2、提升服务人员素质 3、规范服务流程 三、打造乡村旅游品牌 1、挖掘乡村文化特色 2、打造特色旅游产品 3、加强品牌宣传和推广 四、增强乡村旅游吸引力 1、创新旅游体验方式 2、打造旅游精品线路 3、…

【力扣】矩阵中的最长递增路径

一、题目描述 二、解题思路 1、先求出以矩阵中的每个单元格为起点的最长递增路径 题目中说&#xff0c;对于每个单元格&#xff0c;你可以往上&#xff0c;下&#xff0c;左&#xff0c;右四个方向移动。那么以一个单元格为起点的最长递增路径就是&#xff1a;从该单元格往上…

2021年vue面试题整理(万字解析)

一、对MVVM的理解 MVVM分为Model、View、ViewModel。 Model 代表数据模型&#xff0c;数据和业务逻辑都在Model层中定义&#xff1b;泛指后端进行的各种业务逻辑处理和数据操控&#xff0c;对于前端来说就是后端提供的 api 接口。 View 代表UI视图&#xff0c;负责数据的展示…

Redis-重定向

实验环境&#xff08;3主3从的Redis-Cluster&#xff09; 一、Redis重定向基础篇 1、MOVED重定向 Redis Custer 中&#xff0c;客户端可以向集群中任意节点发送请求。此时当前节点先对 Key 进行 CRC 16 计算&#xff0c;然后按 16384 取模确定 Slot 槽。确定该 Slot 槽所对应的…

postgresql之翻页优化

列表和翻页是所有应用系统里面必不可少的需求&#xff0c;但是当深度翻页的时候&#xff0c;越深越慢。下面是几种常用方式 准备工作 CREATE UNLOGGED TABLE data (id bigint GENERATED ALWAYS AS IDENTITY,value double precision NOT NULL,created timestamp with time zon…

AI大模型日报#0607:10家国产大模型、GPT-4o挑战高考作文 | OpenAI公开破解GPT-4新方法

导读&#xff1a;AI大模型日报&#xff0c;爬虫LLM自动生成&#xff0c;一文览尽每日AI大模型要点资讯&#xff01;目前采用“文心一言”&#xff08;ERNIE 4.0&#xff09;、“零一万物”&#xff08;Yi-Large&#xff09;生成了今日要点以及每条资讯的摘要。欢迎阅读&#xf…

新媒体暴力起号必备因素!沈阳新媒体运营培训学校

1周涨粉10w&#xff1f;这对普通人来说可以说是天文数字&#xff0c;但只要掌握方式方法&#xff0c;普通人也能做到&#xff01; 面试经验丰富的人都深知&#xff0c;给面试官留下的第一印象相当重要&#xff0c;几乎决定了80%的面试机会。标题也是如此&#xff0c;在完成一篇…