当前位置: 首页 > news >正文

算法【双向广搜】

双向广搜常见用途

1:小优化。bfs的剪枝策略,分两侧展开分支,哪侧数量少就从哪侧展开。

2:用于解决特征很明显的一类问题。特征:全量样本不允许递归完全展开,但是半量样本可以完全展开。过程:把数据分成两部分,每部分各自展开计算结果,然后设计两部分结果的整合逻辑。

下面通过几个题目加深理解。

题目一

测试链接:https://leetcode.cn/problems/word-ladder

分析:这个就是双向广搜的第一个用途。分别从beginWord和endWord开始广度优先遍历,得到转换成的单词序列,对于得到的两个单词序列,选择单词数较少的,再次使用广度优先遍历。当得到的单词序列中,有和另一序列中重复的单词,代表beginWord可以转化成endWord。如果广度优先遍历的次数大于wordList的长度加1则代表不能转换。代码如下。

class Solution {
public:set<string> beginLevel;set<string> endLevel;set<string> nextLevel;set<string> dict;void build(string beginWord, string endWord, vector<string>& wordList){int length = wordList.size();for(int i = 0;i < length;++i){dict.insert(wordList[i]);}beginLevel.insert(beginWord);endLevel.insert(endWord);}int ladderLength(string beginWord, string endWord, vector<string>& wordList) {build(beginWord, endWord, wordList);set<string> temp;int ans = 0;string cur;char cur_char;int cur_length;if(dict.count(endWord) == 0){return ans;}ans += 2;while (true){if(beginLevel.size() <= endLevel.size()){for(set<string>::iterator it = beginLevel.begin();it != beginLevel.end();++it){cur = *it;cur_length = cur.size();for(int i = 0;i < cur_length;++i){cur_char = cur[i];for(char j = 'a';j <= 'z';++j){cur[i] = j;if(dict.count(cur) != 0 && j != cur_char){if(endLevel.count(cur) != 0){return ans;}else{nextLevel.insert(cur);}}}cur[i] = cur_char;}}temp = beginLevel;beginLevel = nextLevel;nextLevel = temp;nextLevel.clear();++ans;}else{for(set<string>::iterator it = endLevel.begin();it != endLevel.end();++it){cur = *it;cur_length = cur.size();for(int i = 0;i < cur_length;++i){cur_char = cur[i];for(char j = 'a';j <= 'z';++j){cur[i] = j;if(dict.count(cur) != 0 && j != cur_char){if(beginLevel.count(cur) != 0){return ans;}else{nextLevel.insert(cur);}}}cur[i] = cur_char;}}temp = endLevel;endLevel = nextLevel;nextLevel = temp;nextLevel.clear();++ans;}if(ans > wordList.size()+1){break;}}return 0;}
};

其中,采用哈希表来快速判断是否有重复单词。

题目二

测试链接:https://www.luogu.com.cn/problem/P4799

分析:这个就是双向广搜的第二个用途。刚拿到这个题,会很容易地想到使用动态规划,但是一看到数据量就知道一定会超时。而将每场门票分成两部分,分别使用广度优先搜索,得到每一种搭配的花费。对这两部分使用广度优先搜索得到的搭配,从小到大排序后使用双指针即可得到所有方案的个数。代码如下。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int N;
long long M;
long long price[40];
vector<long long> l;
vector<long long> r;
void f(int i, int e, long long sum, long long bound, vector<long long> &ans){if(sum > bound){return ;}if(i == e){ans.push_back(sum);}else{f(i+1, e, sum, bound, ans);f(i+1, e, sum+price[i], bound, ans);}
}
int main(void){int middle;long long left, right;long long l_length, r_length;long long ans = 0;scanf("%d%ld", &N, &M);for(int i = 0;i < N;++i){scanf("%ld", &price[i]);}middle = N / 2;f(0, middle, 0, M, l);f(middle, N, 0, M, r);sort(l.begin(), l.end());sort(r.begin(), r.end());l_length = l.size();r_length = r.size();left = 0;right = r_length-1;for(;left < l_length && right >= 0;++left){while (right >= 0 && l[left] + r[right] > M){--right;}if(right >= 0){ans += (right + 1);}}printf("%ld", ans);
}

其中,f函数是一个递归函数,代表下标从i到e,当前和为sum,不能超过bound的搭配的花费,将花费存储在ans数组中;得到了l和r两个花费数组后排序,然后利用双指针,搭配数组两边之和不超过bound就代表是一种方案。

题目三

测试链接:https://leetcode.cn/problems/closest-subsequence-sum

分析:这道题和题目二基本一致。主体代码相同,只是求的东西不一样。代码如下。

class Solution {
public:vector<int> l;vector<int> r;void f(int i, int e, int sum, int bound, vector<int> &ans, vector<int>& nums){if(i == e){ans.push_back(sum);}else{f(i+1, e, sum, bound, ans, nums);f(i+1, e, sum+nums[i], bound, ans, nums);}}int minAbsDifference(vector<int>& nums, int goal) {int length = nums.size();int ans = -((1 << 31) + 1);f(0, length/2, 0, goal, l, nums);f(length/2, length, 0, goal, r, nums);sort(l.begin(), l.end());sort(r.begin(), r.end());int l_length = l.size();int r_length = r.size();int left = 0, right = r_length-1;for(;left < l_length && right >= 0;++left){while (right >= 0 && l[left] + r[right] > goal){--right;}if(right >= 0){ans = ans < abs(l[left] + r[right] - goal) ? ans : abs(l[left] + r[right] - goal);if(right < r_length-1){ans = ans < abs(l[left] + r[right+1] - goal) ? ans : abs(l[left] + r[right+1] - goal);}}else{ans = ans < abs(l[left] + r[0] - goal) ? ans : abs(l[left] + r[0] - goal);}}return ans;}
};

其中,主体代码也是利用f函数得到搭配序列,然后排序,使用双指针得到结果。

相关文章:

算法【双向广搜】

双向广搜常见用途 1&#xff1a;小优化。bfs的剪枝策略&#xff0c;分两侧展开分支&#xff0c;哪侧数量少就从哪侧展开。 2&#xff1a;用于解决特征很明显的一类问题。特征&#xff1a;全量样本不允许递归完全展开&#xff0c;但是半量样本可以完全展开。过程&#xff1a;把…...

javascript检测数据类型的方法

1. typeof 运算符 typeof是一个用来检测变量的基本数据类型的运算符。它可以返回以下几种类型的字符串&#xff1a;“undefined”、“boolean”、“number”、“string”、“object”、“function” 和 “symbol”&#xff08;ES6&#xff09;。需要注意的是&#xff0c;对于 n…...

生信初学者教程(五):R语言基础

文章目录 数据类型整型逻辑型字符型日期型数值型复杂数数据结构向量矩阵数组列表因子数据框ts特殊值缺失值 (NA)无穷大 (Inf)非数字 (NaN)安装R包学习材料R语言是一种用于统计计算和图形展示的编程语言和软件环境,广泛应用于数据分析、统计建模和数据可视化。1991年:R语言的最…...

深度学习计算

一、层和块 块可以描述单个层、多个层组成的组件或整个模型。 通过定义块&#xff0c;组装块&#xff0c;可以实现复杂的神经网络。 一个块可以由多个class组成。 其实就是 自己定义神经网络net&#xff0c;自己定义层的顺序和具体的init、 forward函数。 层和块的顺序由sequen…...

Hexo博客私有部署Twikoo评论系统并迁移评论记录(自定义邮件回复模板)

部署 之前一直使用的artalk&#xff0c;现在想改用Twikoo&#xff0c;采用私有部署的方式。 私有部署 (Docker) 端口可以根据实际情况进行修改 docker run --name twikoo -e TWIKOO_THROTTLE1000 -p 8100:8100 -v ${PWD}/data:/app/data -e TWIKOO_PORT8100 -d imaegoo/twi…...

Vue.js 与 Flask/Django 后端配合:构建现代 Web 应用的最佳实践

Vue.js 与 Flask/Django 后端配合&#xff1a;构建现代 Web 应用的最佳实践 在现代 Web 开发中&#xff0c;前后端分离的架构已经成为主流。Vue.js 作为一个渐进式 JavaScript 框架&#xff0c;因其灵活性和易用性而广受欢迎。而 Flask 和 Django 则是 Python 生态中两个非常流…...

【笔记】自动驾驶预测与决策规划_Part3_路径与轨迹规划

文章目录 0. 前言1. 基于搜索的路径规划1.1 A* 算法1.2 Hybrid A* 算法 2. 基于采样的路径规划2.1 Frent Frame方法2.2 Cartesian →Frent 1D ( x , y ) (x, y) (x,y) —> ( s , l ) (s, l) (s,l)2.3 Cartesian →Frent 3D2.4 贝尔曼Bellman最优性原理2.5 高速轨迹采样——…...

Shiro-721—漏洞分析(CVE-2019-12422)

文章目录 Padding Oracle Attack 原理PKCS5填充怎么爆破攻击 漏洞原理源码分析漏洞复现 本文基于shiro550漏洞基础上分析&#xff0c;建议先看上期内容&#xff1a; https://blog.csdn.net/weixin_60521036/article/details/142373353 Padding Oracle Attack 原理 网上看了很多…...

【Python语言初识(一)】

一、python简史 1.1、python的历史 1989年圣诞节&#xff1a;Guido von Rossum开始写Python语言的编译器。1991年2月&#xff1a;第一个Python编译器&#xff08;同时也是解释器&#xff09;诞生&#xff0c;它是用C语言实现的&#xff08;后面&#xff09;&#xff0c;可以调…...

Python 中的方法解析顺序(MRO)

在 Python 中&#xff0c;MRO&#xff08;Method Resolution Order&#xff0c;方法解析顺序&#xff09;是指类继承体系中&#xff0c;Python 如何确定在调用方法时的解析顺序。MRO 决定了在多继承环境下&#xff0c;Python 如何寻找方法或属性&#xff0c;即它会根据一定规则…...

MySQL表的内外连接

内连接 其实就是from 两个表 把笛卡尔积的表 再用where 进行条件筛选 ——之前我们写的多表查询就是内连接 基本格式&#xff1a; 外链接 没有向内连接那样真的把两个表连接形式一个表显示&#xff0c;而只是建立关系 外连接分为左链接和右链接 左链接 联合查询时候&#…...

系统架构设计师:软件架构的演化和维护

简简单单 Online zuozuo: 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo :本心、输入输出、结果 简简单单 Online zuozuo : 文章目录 系统架构设计师:软件架构的演化和维护前言软件架构演化的重要性面向对象的软件架构演…...

QT的dropEvent函数进入不了

在使用QT想实现拖拽功能的时候&#xff0c;发现了dropEvent没有调用运行&#xff0c;遂查找原因&#xff1a; 首先是网上都说要在dragEnterEvent里面使用event->accept(); 但我这边在出现问题之前就已经这样做了&#xff1a; void CanvasView::dragEnterEvent(QDragEnterEv…...

Spring Boot 入门

前言 Spring Boot 是一个开源的 Java 基础框架&#xff0c;用于创建独立、生产级的基于 Spring 的应用程序。它简化了基于 Spring 的应用开发&#xff0c;通过提供一系列的“起步依赖”来快速启动和运行 Spring 应用。本文将带你深入了解 Spring Boot 的核心概念、关键特性&am…...

LDD学习2--Scull(TODO)

《Linux Device Drivers》&#xff08;LDD&#xff09;书籍中的 scull&#xff08;Simple Character Utility for Loading Localities&#xff09;是一个用于演示 Linux 字符设备驱动程序编写的示例代码。它为理解 Linux 内核模块和字符设备驱动程序的编写提供了基础实践平台&a…...

【算法-堆排序】

堆排序是一种基于堆这种数据结构的比较排序算法&#xff0c;它是一种原地、不稳定的排序算法&#xff0c;时间复杂度为 O(n log n)。堆排序的基本思想是将数组构建成一个二叉堆&#xff0c;并通过反复调整堆顶和未排序部分之间的关系来实现排序。 堆的定义 堆是一种特殊的完全…...

音视频入门基础:AAC专题(4)——ADTS格式的AAC裸流实例分析

音视频入门基础&#xff1a;AAC专题系列文章&#xff1a; 音视频入门基础&#xff1a;AAC专题&#xff08;1&#xff09;——AAC官方文档下载 音视频入门基础&#xff1a;AAC专题&#xff08;2&#xff09;——使用FFmpeg命令生成AAC裸流文件 音视频入门基础&#xff1a;AAC…...

【第33章】Spring Cloud之SkyWalking服务链路追踪

文章目录 前言一、介绍1. 架构图2. SkyWalking APM 二、服务端和控制台1. 下载2. 解压3. 初始化数据库4. 增加驱动5. 修改后端配置6. 启动7. 访问控制台8. 数据库表 三、客户端1. 下载2. 设置java代理3. idea配置3.1 环境变量3.2 JVM参数3.3 启动日志 4. 启用网关插件 四、链路…...

如何选择OS--Linux不同Distribution的选用

写在前言&#xff1a; 刚写了Windows PC的不同editions的选用&#xff0c;趁热&#xff0c;把Linux不同的Distribution选用也介绍下&#xff0c;希望童鞋们可以了解-->理解-->深入了解-->深入理解--...以致于能掌握特定版本的Linux的使用甚者精通。……^.^…… so&a…...

cesium效果不酷炫怎么办--增加渲染器

DrawCommand 可以发挥 WebGL 全部潜力吗&#xff1f; 回答&#xff1a; Cesium 的 DrawCommand 是一个用于表示 WebGL 渲染管线中单个绘制调用的低级抽象。它封装了执行 WebGL 绘制所需的所有信息&#xff0c;包括着色器程序、顶点数组、渲染状态、统一变量&#xff08;unifo…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

el-switch文字内置

el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

【 java 虚拟机知识 第一篇 】

目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?

在工业自动化持续演进的今天&#xff0c;通信网络的角色正变得愈发关键。 2025年6月6日&#xff0c;为期三天的华南国际工业博览会在深圳国际会展中心&#xff08;宝安&#xff09;圆满落幕。作为国内工业通信领域的技术型企业&#xff0c;光路科技&#xff08;Fiberroad&…...

Python爬虫实战:研究Restkit库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的有价值数据。如何高效地采集这些数据并将其应用于实际业务中,成为了许多企业和开发者关注的焦点。网络爬虫技术作为一种自动化的数据采集工具,可以帮助我们从网页中提取所需的信息。而 RESTful API …...

【1】跨越技术栈鸿沟:字节跳动开源TRAE AI编程IDE的实战体验

2024年初&#xff0c;人工智能编程工具领域发生了一次静默的变革。当字节跳动宣布退出其TRAE项目&#xff08;一款融合大型语言模型能力的云端AI编程IDE&#xff09;时&#xff0c;技术社区曾短暂叹息。然而这一退场并非终点——通过开源社区的接力&#xff0c;TRAE在WayToAGI等…...

华为OD机考- 简单的自动曝光/平均像素

import java.util.Arrays; import java.util.Scanner;public class DemoTest4 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint[] arr Array…...