算法系列--递归,回溯,剪枝的综合应用(2)

在这里插入图片描述

💕"对相爱的人来说,对方的心意,才是最好的房子。"💕
作者:Lvzi
文章主要内容:算法系列–递归,回溯,剪枝的综合应用(2)
在这里插入图片描述

大家好,今天为大家带来的是算法系列--递归,回溯,剪枝的综合应用(2)

一.括号⽣成

题目链接

括号生成

题目描述

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

示例:

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

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

提示:

  • 1 <= n <= 8

分析:
在这里插入图片描述

代码:

class Solution {List<String> ret;// 返回值StringBuffer path;// 记录搜索路径int maxLevel, lcnt, rcnt;// max表示最大层数  lcnt表示左括号的数量  rcnt表示右括号的数量public List<String> generateParenthesis(int n) {ret = new ArrayList<>();path = new StringBuffer();if (n == 0) return ret;maxLevel = 2 * n;dfs(1, lcnt, rcnt,n);return ret;}private void dfs(int level, int lcnt, int rcnt,int n) {// 递归出口if(level > maxLevel) {ret.add(path.toString());return;}if(lcnt < n) {path.append("(");dfs(level + 1,lcnt+1, rcnt,n);path.deleteCharAt(path.length() - 1);// 回溯}if(rcnt < n && lcnt > rcnt) {path.append(")");dfs(level + 1, lcnt, rcnt+1,n);path.deleteCharAt(path.length() - 1);// 回溯}}
}

二.目标和

题目链接

目标和

题目描述

给你一个非负整数数组 nums 和一个整数 target

向数组中的每个整数前添加 ‘+’ 或 ‘-’ ,然后串联起所有整数,可以构造一个表达式:

例如,nums = [2, 1] ,可以在 2 之前添加 ‘+’ ,在 1 之前添加 ‘-’ ,然后串联起来得到表达式 "+2-1"

返回可以通过上述方法构造的、运算结果等于 target 的不同表达式的数目。

示例:

  • 输入:nums = [1,1,1,1,1], target = 3
    输出:5
    解释:一共有 5 种方法让最终目标和为 3
    -1 + 1 + 1 + 1 + 1 = 3
    +1 - 1 + 1 + 1 + 1 = 3
    +1 + 1 - 1 + 1 + 1 = 3
    +1 + 1 + 1 - 1 + 1 = 3
    +1 + 1 + 1 + 1 - 1 = 3

  • 输入:nums = [1], target = 1
    输出:1

提示:

  • 1 <= nums.length <= 20
  • 0 <= nums[i] <= 1000
  • 0 <= sum(nums[i]) <= 1000
  • -1000 <= target <= 1000

分析:

思路同子集相同,子集中我们的决策策略是选不选当前的数,本题采用+当前数/-当前数

在这里插入图片描述

代码:

class Solution {int path, ret, target;public int findTargetSumWays(int[] nums, int _target) {target = _target;dfs(nums,0);return ret;}private void dfs(int[] nums, int pos) {if(pos == nums.length) {if(path == target)  ret += 1;return;}// +path += nums[pos];dfs(nums,pos + 1);path -= nums[pos];//回溯// -path -= nums[pos];dfs(nums,pos + 1);path += nums[pos];// 回溯}
}

本题的最优解法其实是动态规划,具体可见我的这篇文章
算法系列–动态规划–背包问题(2)–01背包拓展题目

(有限制条件下的组合问题,且一个数只能选择一次–01背包问题)


3.组合总和

题目链接

组合总和

题目描述

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

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

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

示例:

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

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

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

提示:

  • 1 <= candidates.length <= 30
  • 2 <= candidates[i] <= 40
  • candidates 的所有元素互不相同
  • 1 <= target <= 40

分析:
在这里插入图片描述

(如果本题是要求组合总和的最多组合数就是一个完全背包问题)

代码:

class Solution {List<List<Integer>> ret;List<Integer> path;// 保存搜索路径int sum, target;// sum记录搜索路径上的和public List<List<Integer>> combinationSum(int[] nums, int _target) {ret = new ArrayList<>();path = new ArrayList<>();target = _target;dfs(nums,0);return ret;}private void dfs(int[] nums, int pos) {if(sum >= target) {// 递归出口if(sum == target) {ret.add(new ArrayList<>(path));}return;}for(int i = pos; i < nums.length; i++) {path.add(nums[i]); sum += nums[i];dfs(nums,i);// 递归path.remove(path.size() - 1); sum -= nums[i];// 回溯}}
}

4.字⺟⼤⼩写全排列

题目链接

字⺟⼤⼩写全排列

题目描述

784. 字母大小写全排列

给定一个字符串 s,通过将字符串 s 中的每个字母转变大小写,我们可以获得一个新的字符串。

返回所有可能得到的字符串集合。以任意顺序返回输出。

示例:

  • 输入:s = “a1b2”
    输出:[“a1b2”, “a1B2”, “A1b2”, “A1B2”]

  • 输入: s = “3z4”
    输出: [“3z4”,“3Z4”]

提示:

  • 1 <= s.length <= 12
  • s 由小写英文字母、大写英文字母和数字组成

解题思路

这道题可以使用回溯算法来解决。我们可以逐个遍历字符串中的每个字符,然后对于每个字符有两种选择:保持原大小写或者转换大小写。通过递归实现所有可能的组合。

代码实现(Java)

class Solution {List<String> ret;StringBuffer path;public List<String> letterCasePermutation(String s) {ret = new ArrayList<>();path = new StringBuffer();dfs(s,0);return ret;}private void dfs(String s, int pos) {if(pos == s.length()) {ret.add(path.toString());return;}// 不改变char ch = s.charAt(pos);path.append(ch);dfs(s, pos + 1);path.deleteCharAt(path.length() - 1);// 改变(非数字字符)if(ch < '0' || ch > '9') {char tmp = change(ch);path.append(tmp);dfs(s, pos + 1);path.deleteCharAt(path.length() - 1);}}private char change(char ch) {if(ch >= 'a' && ch <= 'z') return ch -= 32;else return ch += 32;}
}

5.优美的排列

题目链接

优美的排列

题目描述

526. 优美的排列

假设有从 1 到 n 的 n 个整数。用这些整数构造一个数组 perm(下标从 1 开始),只要满足下述条件之一,该数组就是一个优美的排列:

  1. perm[i] 能够被 i 整除
  2. i 能够被 perm[i] 整除

给你一个整数 n ,返回可以构造的优美排列的数量。

示例:

输入:n = 2

输出:2

解释:

  • 第 1 个优美的排列是 [1,2]:
    • perm[1] = 1 能被 i = 1 整除
    • perm[2] = 2 能被 i = 2 整除
  • 第 2 个优美的排列是 [2,1]:
    • perm[1] = 2 能被 i = 1 整除
    • i = 2 能被 perm[2] = 1 整除

解题思路

这道题可以使用回溯算法来解决。我们可以尝试将数字填充到数组的每个位置上,同时检查当前位置是否满足条件。如果满足条件,继续递归处理下一个位置;否则,回溯到上一个位置重新尝试其他数字。

  • check[i]:用于标记数字是否被使用过
  • ret:返回值

代码实现(Java)

class Solution {int ret;// 返回值boolean[] check;// 用于标记已经使用过的数字public int countArrangement(int n) {check = new boolean[n + 1];dfs(1,n);return ret;}private void dfs(int pos, int n) {// pos是下标if(pos == n + 1) {// 递归出口ret += 1;return;}for(int i = 1; i <= n; i++) {if(check[i] == false && (pos % i == 0 || i % pos == 0)) {check[i] = true;// 将使用过的数字标记dfs(pos + 1, n);// 递归下一个位置check[i] = false;// 回溯}}}
}

在这段代码中:

  • pos 表示当前递归到的位置,也就是在填充数组时当前正在考虑的位置。
  • i 则表示尝试填充到当前位置 pos 上的数字。

具体来说:

  • pos 从1开始,代表数组中的位置,递归函数会尝试将数字填充到这些位置上。
  • i 从1到n,代表可以填充到当前位置的数字,即数组中的元素。

6. 组合

题目链接

组合

题目描述

给定两个整数 nk,返回范围 [1, n] 中所有可能的 k 个数的组合。

你可以按任何顺序返回答案。

示例 1:

输入:n = 4, k = 2
输出:

[[2,4],[3,4],[2,3],[1,2],[1,3],[1,4],
]

示例 2:

输入:n = 1, k = 1
输出:[[1]]

提示:

  • 1 <= n <= 20
  • 1 <= k <= n

分析:
在这里插入图片描述

代码:

class Solution {List<List<Integer>> ret;List<Integer> path;int k, n;public List<List<Integer>> combine(int nn, int kk) {n = nn; k = kk;ret = new ArrayList<>();path = new ArrayList<>();dfs(1);return ret;}private void dfs(int start) {if(path.size() == k) {ret.add(new ArrayList<>(path));return;}for(int i = start; i <= n; i++) {path.add(i);// 添加当前数字dfs(i + 1);// 递归下一个数字path.remove(path.size() - 1);// 回溯}}
}

总结:

  • 对于递归回溯这样的问题,一定要把决策树画的详细,要明确每一步的目的是什么,是根据什么进行递归的

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java的IDEA的工程管理

模块和包的图标&#xff1a; 举个例子&#xff1a; IDEA中创建包&#xff1a; 如图所示&#xff0c;com.LBJ的意思是在com包中创建子包LBJ 参见&#xff1a; IDEA中项目、模块和包的关系_idea中模块和项目-CSDN博客

llama-index 结合chatglm3-6B 利用RAG 基于文档智能问答

简介 llamaindex结合chatglm3使用 import os import torch from llama_index.core import VectorStoreIndex, ServiceContext from llama_index.core.callbacks import CallbackManager from llama_index.core.llms.callbacks import llm_completion_callback from llama_ind…

使用STM32 MCU模拟实现PPS+TOD授时信号

简介 PPSTOD是授时信号的一种&#xff0c;用来传递准确的时间信息。 PPS&#xff0c;Pulse Per Second&#xff0c;是每秒一次的脉冲信号&#xff0c;其上升沿表示整秒的时刻。TOD&#xff0c;Time of Day&#xff0c;是时间信息。是跟随在每个PPS信号后的由串口发出的一句报…

HTML——4.表格、列表、区块

一、表格 HTML 表格是用于展示结构化数据的重要元素&#xff0c;它允许将数据以行和列的形式组织和显示。 基本结构和常见元素&#xff1a; 1. <table> 元素 <table> 元素是 HTML 表格的根元素&#xff0c;它用于定义整个表格的开始和结束。 2. <thead>、…

曼哈顿距离和切比雪夫距离

曼哈顿距 定义 设平面空间内存在两点&#xff0c;它们的坐标为(x1,y1) (x2,y2) . 则 dis|x1−x2||y1−y2|&#xff0c;即两点横纵坐标差之和 切比雪夫距离 定义 设平面空间内存在两点&#xff0c;它们的坐标为(x1,y1)&#xff0c;(x2,y2) 则dismax(|x1−x2|,|y1−y2|)&a…

JumpServer 堡垒主机

JumpServer 堡垒机帮助企业以更安全的方式管控和登陆各种类型的资产 SSH&#xff1a;Linux/Unix/网络设备等Windows&#xff1a;Web方式连接/原生RDP连接数据库&#xff1a;MySQL、Oracle、SQLServer、PostgreSQL等Kubernetes&#xff1a;连接到K8s集群中的PodsWeb站点&#x…

微服务之分布式事务概念

微服务之分布式事务概念 CAP定理和Base理论 CAP定理 CAP定理在1998年被加州大学的计算机科学家 Eric Brewer 提出&#xff0c;分布式系统有三个指标&#xff1a; 一致性&#xff08;Consistency&#xff09;可用性&#xff08;Availability&#xff09;分区容错性&#xff…

Vastbase编程利器:PL/pgSQL原理简介

PL/pgSQL是Vastbase提供的一种过程语言&#xff0c;在普通SQL语句的使用上增加了编程语言的特点&#xff0c;可以用于创建函数、存储过程、触发器过程以及创建匿名块等。 本文介绍Vastbase中PL/pgSQL的执行流程&#xff0c;包括PL/pgSQL的编译与运行。 1、编译 PL/pgSQL的编译…

Netty教程之NIO基础

NIO 介绍 NIO 全称java non-blocking IO&#xff08;非阻塞 I/O&#xff09;&#xff0c;后续提供了一系列改进的输入/输出的新特性&#xff0c;被统称为 NIO(即 New IO)&#xff0c;是同步非阻塞的。 阻塞和非阻塞是进程在访问数据的时候&#xff0c;数据是否准备就绪的一种…

ctf题目

目录 1.文件包含的一道题目&#xff0c;没什么难度&#xff0c; 2.一道sql注入的题目&#xff0c;伪静态 3.限制只能本地访问。 1.文件包含的一道题目&#xff0c;没什么难度&#xff0c; 但是一个点就是它这里去包含的那个文件名就是flag&#xff0c;而不是flag.php也不是f…

CSS实现小车旅行动画实现

小车旅行动画实现 效果展示 CSS 知识点 灵活使用 background 属性下的 repeating-linear-gradient 实现路面效果灵活运用 animation 属性与 transform 实现小车和其他元素的动画效果 动画场景分析 从效果图可以看出需要实现此动画的话&#xff0c;需要position属性控制元素…

学习transformer模型-Dropout的简明介绍

Dropout的定义和目的&#xff1a; Dropout 是一种神经网络正则化技术&#xff0c;它在训练时以指定的概率丢弃一个单元&#xff08;以及连接&#xff09;p。 这个想法是为了防止神经网络变得过于依赖特定连接的共同适应&#xff0c;因为这可能是过度拟合的症状。直观上&#…

移动硬盘无法打开?原因与解决方案一网打尽

一、遭遇困境&#xff1a;移动硬盘突然罢工 在数字化日益盛行的今天&#xff0c;移动硬盘无疑是我们储存和转移数据的重要工具。然而&#xff0c;当某一天你突然发现移动硬盘无法打开时&#xff0c;那种焦虑与无助感无疑会席卷而来。插上电脑&#xff0c;硬盘灯闪烁却无响应&a…

软考之零碎片段记录(二)

一、位示图记录磁盘使用情况 1. 计算位示图的大小&#xff1f; 物理块大小4MB, 磁盘容量512GB, 系统字长64位&#xff08;64位 / 字长&#xff09; 计算物理块数量 512 * 1024 / 4 256 * 512 131072 每一位记录一个物理块 131072 / 64 2048&#xff08;字&#xff09; 二…

科研学习|论文解读——情感对感知偶然信息遭遇的影响研究(JASIST,2022)

原文题目 Investigating the impact of emotions on perceiving serendipitous information encountering 一、引言 serendipity一词最初是由霍勒斯沃波尔创造的&#xff0c;他将其定义为“通过意外和睿智发现你并不追求的事物”。信息研究中大多数现有的偶然性定义从几个角度看…

vue2 el-table指定某些数据不参与排序

vue2 el-table指定某些数据不参与排序 1、需求描述2、配置属性方法3、详细代码如下 1、需求描述 最后一行总计不参与排序 2、配置属性方法 el-table 需要配置 sort-change"soltHandle" 方法 el-table-column 需要配置 sortable"custom"属性3、详细代码如…

单链表的插入和删除

一、插入操作 按位序插入&#xff08;带头结点&#xff09;&#xff1a; ListInsert(&L,i,e):插入操作。在表L中的第i个位置上插入指定元素e。 typedef struct LNode{ElemType data;struct LNode *next; }LNode,*LinkList;//在第i 个位置插插入元素e (带头结点) bool Li…

Bridge Champ与Ignis公链:探索Web3游戏的新未来

在数字化和去中心化的浪潮中&#xff0c;Web3游戏与公链的融合为游戏行业带来了新的变革。特别是&#xff0c;Bridge Champ和Ignis公链的结合&#xff0c;展示了一种全新的游戏生态模式&#xff0c;不仅为玩家提供了更加公平、透明的游戏体验&#xff0c;同时也为游戏开发和运营…

Day50:WEB攻防-PHP应用文件包含LFIRFI伪协议编码算法无文件利用黑白盒

目录 文件包含-原理&分类&利用&修复 文件读取 文件写入 代码执行 远程利用思路 黑盒利用-VULWEB 白盒利用-CTFSHOW-伪协议玩法 78-php&http协议 79-data&http协议 80-81-日志包含 87-php://filter/write&加密编码 88-data&base64协议 …

磐启/PAN7030/2.4GHz 无线收发SOC芯片/ESSOP10/SOP16

1 概述 PAN7030 是一款集成 8 位 OTP MCU 和 2.4GHz 无线收发电路芯片&#xff0c;适合应用于玩具小车、 遥控器等领域。 PAN7030 内置 8 位 OTP MCU&#xff0c;包括 1.25KW 的程序存储器、80 字节数据存储器、16 位定 时器和 8 位/11 位 PWM 定时器、看门狗、电压比较器等…