利用广度优先或模拟解决米诺骨牌

本周推荐阅读

C++二分算法:得到子序列的最少操作次数

题目

n 张多米诺骨牌排成一行,将每张多米诺骨牌垂直竖立。在开始时,同时把一些多米诺骨牌向左或向右推。
每过一秒,倒向左边的多米诺骨牌会推动其左侧相邻的多米诺骨牌。同样地,倒向右边的多米诺骨牌也会推动竖立在其右侧的相邻多米诺骨牌。
如果一张垂直竖立的多米诺骨牌的两侧同时有多米诺骨牌倒下时,由于受力平衡, 该骨牌仍然保持不变。
就这个问题而言,我们会认为一张正在倒下的多米诺骨牌不会对其它正在倒下或已经倒下的多米诺骨牌施加额外的力。
给你一个字符串 dominoes 表示这一行多米诺骨牌的初始状态,其中:
dominoes[i] = ‘L’,表示第 i 张多米诺骨牌被推向左侧,
dominoes[i] = ‘R’,表示第 i 张多米诺骨牌被推向右侧,
dominoes[i] = ‘.’,表示没有推动第 i 张多米诺骨牌。
返回表示最终状态的字符串。
示例 1:
输入:dominoes = “RR.L”
输出:“RR.L”
解释:第一张多米诺骨牌没有给第二张施加额外的力。
示例 2:
输入:dominoes = “.L.R…LR…L…”
输出:“LL.RR.LLRRLL…”
提示:
n == dominoes.length
1 <= n <= 105
dominoes[i] 为 ‘L’、‘R’ 或 ‘.’
![(https://img-blog.csdnimg.cn/7ddeab69c86f43ee9c3a704d603a85f4.png#pic_center)
在这里插入图片描述

初始想法

将LR放到栈中。

如果遇到两个L则两个L之间的全部L ,出栈入栈
栈顶L,新遇到R不处理,新元素入栈
如果遇到两个R两个R之间全部R,出栈入栈
栈顶R 新遇到LRL之间离R近的R,离L近的L,相等的不边,出栈入栈

结束时,栈有如下几种情况

LR
L
R

分情况讨论过于复杂,放弃。

可行的方案

时间复杂度: O(n) ,两轮循环时间复杂度都是O(n)。

分析

向左倒右边必须有牌向左倒,且不被向右倒的牌挡住
向右倒左边必须有牌向右倒,且不被向左倒的牌挡住
左右倒距离左倒的近,左倒;距离右倒的近,右倒;距离相等,直立

变量解释

vRight距离最近的向右倒的牌的索引
iLeft距离最近向左倒的牌的索引

核心代码

class Solution {
public:string pushDominoes(string dominoes) {m_c = dominoes.length();vector<int> vRight(m_c, -1);{int iRight = -1;for (int i = 0; i < m_c; i++){if ('R' == dominoes[i]){iRight = i;}if ('L' == dominoes[i]){iRight = -1;}vRight[i] = iRight;}}int iLeft = -1;string s(m_c, '.');for (int i = m_c - 1; i >= 0; i--){if ('L' == dominoes[i]){iLeft = i;}if ('R' == dominoes[i]){iLeft = -1;}			if (iLeft >= 0){if (vRight[i] >= 0){int tmp = (iLeft - i) - (i - vRight[i]);if (tmp > 0){s[i] = 'R';}else if (tmp < 0){s[i] = 'L';}}else{s[i] = 'L';}}else if(vRight[i] >= 0){s[i] = 'R';}}return s;}int m_c;
};

测试用例

template <class T>
void Assert(const T& t1, const T& t2)
{assert(t1 == t2);
}template <class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{if (v1.size() != v2.size()){assert(false);return;}for (int i = 0; i < v1.size(); i++){Assert(v1[i], v2[i]);}
}int main()
{string dominoes;string res;{Solution slu;dominoes = "...";res = slu.pushDominoes(dominoes);Assert(res, string("..."));}{Solution slu;dominoes = ".L.";res = slu.pushDominoes(dominoes);Assert(res, string("LL."));}{Solution slu;dominoes = ".R.";res = slu.pushDominoes(dominoes);Assert(res, string(".RR"));}{Solution slu;dominoes = "R";res = slu.pushDominoes(dominoes);Assert(res, string("R"));}{Solution slu;dominoes = "L";res = slu.pushDominoes(dominoes);Assert(res, string("L"));}{Solution slu;dominoes = ".";res = slu.pushDominoes(dominoes);Assert(res, string("."));}{Solution slu;		dominoes = "RR.L";res = slu.pushDominoes(dominoes);Assert(res, string("RR.L"));}{Solution slu;dominoes = ".L.R...LR..L..";res = slu.pushDominoes(dominoes);Assert(res, string("LL.RR.LLRRLL.."));}//CConsole::Out(res);
}

深度优先搜索

分析

时间复杂度: O(n) ,每个元素最多出队入队一次。

变量解释

que记录当前回合左到或右倒的元素索引
mIndexValue键:当前回合受到力的牌,值:当前回合受到力。1,向左的力;0,没受到力或同时受到左右的力。-1,受到向右的力。

注意: 力值能让没倒的牌倒下,无法让倒下的牌转变方向。

if ('.' != dominoes[it.first]){continue;}

代码

class Solution {
public:string pushDominoes(string dominoes) {m_c = dominoes.length();std::queue<int> que;for (int i = 0; i < m_c; i++){if ('.' != dominoes[i]){que.emplace(i);}}while (que.size()){unordered_map<int, int> mIndexValue;while (que.size()){const int inx = que.front();que.pop();if ('L' == dominoes[inx]){if (inx > 0){mIndexValue[inx - 1]++;}}else {if (inx + 1 < m_c){mIndexValue[inx + 1]--;}}}for (const auto& it : mIndexValue){if ('.' != dominoes[it.first]){continue;}if (1 == it.second){dominoes[it.first] = 'L';que.emplace(it.first);}if (-1 == it.second){dominoes[it.first] = 'R';que.emplace(it.first);}}}return dominoes;}int m_c;
};

模拟

分析

时间复杂度😮(n)。
枚举所有连续的直立牌,根据两边的受力方向分情况讨论。为了简化问题:可以想象在最左边增加L,最右边增加R。

LL全部左倒
LR全部不边
RL左边右倒,右边左倒
RR全部右倒

代码

class Solution {
public:string pushDominoes(string dominoes) {m_c = dominoes.length();int iPre = -1;for (int i = 0; i < m_c; i++){if ('.' != dominoes[i]){Do(dominoes,iPre, i);iPre = i;}}	Do(dominoes, iPre, m_c);return dominoes;}void Do(string& s, int left, int right){const char chL = (left < 0) ? 'L' : s[left];const char chR = (right < m_c) ? s[right] : 'R';if ('L' == chL){if ('L' == chR){for (int i = left + 1; i < right; i++){s[i] = 'L';}}else{//什么都不干}}else{if ('L' == chR){for (int i = 1; i <= (right - left - 1) / 2; i++){s[left + i] = 'R';s[right - i] = 'L';}}else{for (int i = left + 1; i < right; i++){s[i] = 'R';}}}}int m_c;
};

2022年12月旧版

class Solution {
public:
string pushDominoes(string dominoes) {
c = dominoes.length();
std::unordered_map<int, int> mPreIndexValue;
for (int i = 0; i < c; i++)
{
const char& ch = dominoes[i];
Test(mPreIndexValue,ch, i);
}
while (mPreIndexValue.size())
{
std::unordered_map<int, int> dp;
for (auto& it : mPreIndexValue)
{
if (0 == it.second)
{
continue;
}
if (‘.’ != dominoes[it.first])
{
continue;
}
dominoes[it.first] = (1 == it.second) ? ‘L’ : ‘R’;
Test(dp,dominoes[it.first], it.first);
}
dp.swap(mPreIndexValue);
}
return dominoes;
}
void Test(std::unordered_map<int, int>& m,const char& ch, int i)
{
if (‘L’ == ch)
{
if (i > 0 )
{
m[i - 1]++;
}
}
else if (‘R’ == ch)
{
if (i + 1 < c)
{
m[i + 1]–;
}
}
}
int c;

};

2023年11月旧版

class Solution {
public:
string pushDominoes(string dominoes) {
int n = dominoes.size();
vector vRight(n, -1);
{
int iR = -1;
for (int i = 0; i < n; i++)
{
if (‘R’ == dominoes[i])
{
iR = i;
}
else if (‘L’ == dominoes[i])
{
iR = -1;
}
vRight[i] = iR;
}
}
int iLeft = -1;
string s(n, ‘.’);
for (int i = n - 1; i >= 0; i–)
{
if (‘L’ == dominoes[i])
{
iLeft = i;
}
else if (‘R’ == dominoes[i])
{
iLeft = -1;
}
if ((iLeft >= 0)&&(vRight[i] >= 0 ))
{
const int tmp = (iLeft - i) - (i - vRight[i]);
if (tmp > 0)
{
s[i] = ‘R’;
}
if (tmp < 0)
{
s[i] = ‘L’;
}
}
else if (iLeft >= 0)
{
s[i] = ‘L’;
}
else if (vRight[i] >= 0)
{
s[i] = ‘R’;
}
}
return s;
}
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境:

VS2022 C++17

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

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

相关文章

Python基础教程:强大的Pandas数据分析库

Pandas是一个基于 NumPy 的非常强大的开源数据处理库&#xff0c;它提供了高效、灵活和丰富的数据结构和数据分析工具&#xff0c;当涉及到数据分析和处理时&#xff0c;使得数据清洗、转换、分析和可视化变得更加简单和高效。本文中&#xff0c;我们将学习如何使用Pandas来处理…

BEV+Transformer架构加速“上车”,智能驾驶市场变革开启

BEVTransformer成为了高阶智能驾驶领域最为火热的技术趋势。 近日&#xff0c;在2023年广州车展期间&#xff0c;不少车企及智能驾驶厂商都发布了BEVTransformer方案。其中&#xff0c;极越01已经实现了“BEVTransformer”的“纯视觉”方案的量产&#xff0c;成为国内唯一量产…

使用Pytorch从零开始构建Normalizing Flow

归一化流 (Normalizing Flow) &#xff08;Rezende & Mohamed&#xff0c;2015&#xff09;学习可逆映射 f : X → Z f: X \rightarrow Z f:X→Z, 在这里X是我们的数据分布&#xff0c;Z是选定的潜在分布。 归一化流是生成模型家族的一部分&#xff0c;其中包括变分自动编…

系列二十、Spring循环依赖问题

一、概述 循环依赖是指多个bean之间相互依赖&#xff0c;形成了一个闭环。比如A依赖于B、B依赖于C、C依赖于A&#xff0c;形成了一个圈&#xff0c;如&#xff1a; 二、循环依赖案例 2.1、构造方法注入产生循环依赖案例 2.1.1、ServiceA /*** Author : 一叶浮萍归大海* Date…

AntDB数据库,通信行业20年变迁的见证者

2000年至今&#xff0c;通信行业发展已过了20多年。面对通信行业巨大的数据信息&#xff0c;数据库在行业发展中发挥了巨大的作用&#xff0c;AntDB数据库便是其中较为知名的一款数据库。在通信行业快速发展的阶段&#xff0c;打破国外产品与技术垄断是产业发展的重点与难点。面…

处理分类问题的不平衡数据的 5 种技术

一、介绍 分类问题在机器学习领域很常见。正如我们所知&#xff0c;在分类问题中&#xff0c;我们试图通过研究输入数据或预测变量来预测类标签&#xff0c;其中目标或输出变量本质上是分类变量。 如果您已经处理过分类问题&#xff0c;那么您一定遇到过以下情况&#xff1a;其…

HTML5原生视频播放器组件video的videocontrolslist属性详解

HTML5提供了内置的视频播放控件,其中videocontrolslist是其中一个很有用的属性。videocontrolslist属性可以用于告诉浏览器在视频播放过程中应该显示哪些默认的用户界面控件。下面我们将从几个方面来介绍videocontrolslist的详细使用。 一、启用videocontrolslist videocont…

2024重庆大学计算机考研分析

24计算机考研|上岸指南 重庆大学 重庆大学计算机考研招生学院是计算机学院和大数据与软件学院。目前均已出拟录取名单。 重庆大学计算机学院是我国高校最早开展计算机研究的基地之一&#xff0c;1978年和1986年获西南地区首个硕士和博士点&#xff0c;1998年成立计算机学院&a…

单片机学习2——流水灯的实现

#include<reg52.h>sbit LED P1^0; unsigned char i;void main() {while(1){LED 0;for(i0;i<100;i);LED 1;for(i0;i<100;i);} } RST是复位按钮&#xff0c;单击一下之后&#xff0c;程序就会跑到最开始的位置运行。 右侧的按钮是RUN按钮&#xff0c;单击下&…

ShardingSphere-JDBC 入门教程(v4.1.1)

框架介绍 ShardingSphere-JDBC 定位为轻量级 Java 框架&#xff0c;在 Java 的 JDBC 层提供的额外服务。它使用客户端直连数据库&#xff0c;以 jar 包形式提供服务&#xff0c;无需额外部署和依赖&#xff0c;可理解为增强版的 JDBC 驱动&#xff0c;完全兼容 JDBC 和各种 OR…

利用ogr2ogr从PostGIS中导出/导入Tab/Dxf/Geojson等格式数据

ogr2ogr Demo Command 先查看下当前gdal支持的全部格式&#xff0c;部分gdal版本可能不支持PostGIS。 如出现PostgreSQL表名支持。 #全部支持的格式 ogrinfo --formats | sort #AVCBin -vector- (rov): Arc/Info Binary Coverage #AVCE00 -vector- (rov): Arc/Info E00 (ASC…

数据结构——动态规划

动态规划&#xff1a;有很多重叠子问题&#xff0c;每一个状态一定是由上一个状态推导出来的 贪心&#xff1a;没有状态推导&#xff0c;而是从局部直接选最优的 动规五步曲&#xff1a; 确定dp数组&#xff08;dp table&#xff09;以及下标的含义 确定递推公式&#xff08;容…

STM32-SPI1控制AD7705(Sigma-Delta-ADC芯片)

STM32-SPI1控制AD7705&#xff08;Sigma-Delta-ADC芯片&#xff09; 原理图手册说明功能方框图引脚功能 片内寄存器通信寄存器&#xff08;RS2、RS1、RS00、0、0&#xff09;设置寄存器时钟寄存器数据寄存器&#xff08;RS2、RS1、RS00、1、1&#xff09;测试寄存器&#xff08…

SAP Smartforms设计

第八章 SMART FORMS设计 要点列表 概览&#xff1b; Form&#xff08;表格&#xff09;&#xff1b; Smart Styles&#xff08;样式&#xff09;&#xff1b; Text Module&#xff08;文本模块&#xff09;&#xff1b; 使用标准表方式打印&#xff1b; 使用模板方式打印…

淼一科技为互联网企业销毁硬盘数据 拆除机房设备

在上海这座繁华的大都市&#xff0c;淼一科技以其专业的服务和卓越的技术&#xff0c;为众多互联网企业提供硬盘数据销毁和机房设备拆除服务。作为业界领先的数据安全解决方案提供商&#xff0c;淼一科技致力于保障客户数据的安全与隐私&#xff0c;为客户创造更高的商业价值。…

uni-app:心跳机制基础逻辑(定时器方法解决)

思路 1、在登录的时候&#xff0c;定义一个存储当前时间的全局变量&#xff0c;并且开始心跳请求 2、在全局中定义一个定时器&#xff0c;该定时器每秒都会执行一次&#xff0c;并获取当前的时间 3、将定时器每秒的获取的当前时间和全局变量获取的时间进行比较 4、指定一个…

网络运维与网络安全 学习笔记2023.11.27

网络运维与网络安全 学习笔记 第二十八天 今日目标 OSPF基本原理、OSPF单区域配置、OSPF多区域配置 特殊区域之Stub、特殊区域之NSSA OSPF基本原理 项目背景 随着企业的发展&#xff0c;网络的规模越来越大&#xff0c;网段的数量越来越多&#xff0c;公司内部的路由器的…

Windows系统下搭建PXE Server

在给一台服务器初始安装OS时一般有以下几种方式&#xff1a; 1、通过BMC挂载iso镜像来安装&#xff1b; 2、通过U盘启动来安装&#xff1b; 3、通过网络启动来安装&#xff1b; 方式1和方式2只能一台一台地进行&#xff0c;且需要有键盘和显示器&#xff0c;效率低下&#xff…

在vue页面中添加组件到底有多方便

修改vue写的前端页面到底有多方便&#xff1f;如果熟练的话&#xff0c;出乎你想象的快。 原来的页面&#xff1a;/admin/stock 原来的文件地址&#xff1a;src\views\admin\stock\Stock.vue 另一个页面有个入库功能&#xff0c;需要转移到上面的页面中&#xff1a; 路径&…

基于C#实现块状链表

在数据结构的世界里&#xff0c;我们会认识各种各样的数据结构&#xff0c;每一种数据结构都能解决相应领域的问题&#xff0c;当然每个数据结构&#xff0c;有他的优点&#xff0c;必然就有它的缺点&#xff0c;那么如何创造一种数据结构来将某两种数据结构进行扬长避短&#…