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

news2024/10/5 14:21:40

本周推荐阅读

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.coloradmin.cn/o/1258286.html

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

相关文章

分享:身份证阅读器在ARM Linux系统调用libwlt2bmp.so解码库实现身份证头像解码

头像解码库&#xff1a;libwlt2bmp.so 照片文件名&#xff1a;photo.bmp 原始身份证相片数据&#xff1a;574C66007E00320000F........&#xff08;此处省略&#xff09; 调用身份证阅读器Linux开发包&#xff0c;然后调用libwlt2bmp.so解码库文件&#xff0c;传入身份证原始…

谭巍主任贴心分享:想要HPV尽快转阴必吃的五种水果

HPV感染是常见的生殖道病毒感染&#xff0c;它可能导致宫颈癌等严重疾病。对于HPV感染者来说&#xff0c;转阴是预防和治疗的关键。北京劲松HPV诊疗中心主任谭巍认为除了接受正规的治疗和注意生活方式的调整外&#xff0c;饮食也是促进HPV快速转阴的重要方面。 一、苹果 苹果…

在思岚A1上复现gmapping

文章目录 软硬件条件laser_scan_matcher通过源码安装rplidar_ros通过源码安装设置参数启动效果预览 软硬件条件 软件&#xff1a;Ubuntu 20.04&#xff0c;ROS noetic 硬件&#xff1a;RPLidar A1. laser_scan_matcher通过源码安装 mkdir -p ~/catkin_ws/src cd ~/catkin_w…

特斯拉开源 Roadster 文件随便用;微软 Copilot AI 技术开放或不对大陆开放丨 RTE 开发者日报 Vol.92

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

【数字化转型方法论读书笔记】-数据中台落地实施之法

让数据中台真正落地是实现数字化转型的重中之重。企业做好数据治理、体系建设及人才配备等前期工作后&#xff0c;接下来要做的是数据中台实施落地的关键。 企业首先要掌握数据中台建设的三大核心要素&#xff1a;选对数据建设方式、厘清建设思路、避开数据中台建设误区&#…

Banana Pi最新的路由器板BPI-R4上市销售,基于MediaTek MT7988A

Banana Pi 发布了一款新的路由器板 Banana Pi BPI-R4&#xff0c;基于配备四核 Arm CPU 的 MediaTek MT7988A SoC。该板不仅仅是Raspberry Pi 的另一个替代品&#xff0c;而且是用于家庭网络和自动化的设备。 Banana Pi BPI-R4 的外形尺寸比单板计算机更像网络设备。对于那些希…

ubuntu22.04识别CH340的问题汇总

一、目的 自己的电脑装的是双系统&#xff0c;ubuntu22.04安装了很久好久没有&#xff08;WSL2确实解决了频繁依赖linux的问题&#xff09;。昨天尝试搞一下STM32MP135的系统搭建&#xff0c;开始启用ubuntu22.04。但是遇到了很多问题&#xff0c;其中一个问题就是CH340的驱动…

【JavaScript】3.2 JavaScript性能优化

文章目录 1. 避免全局查找2. 避免不必要的属性查找3. 使用快速的JavaScript方法4. 避免不必要的DOM操作5. 使用Web Workers进行后台处理总结 性能优化是任何编程语言的重要组成部分&#xff0c;JavaScript也不例外。在这个章节中&#xff0c;我们将探讨如何优化JavaScript代码&…

【JavaEE】Java中的多线程 (Thread类)

作者主页&#xff1a;paper jie_博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文录入于《JavaEE》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金(时间和精力)打造&…

c语言,输入整数n(行数,本例为4),按照如下规则打印数字图片 1 5 9 13 2 6 10 14 3 7 11 15 4 8 12 16

c语言&#xff0c;输入整数n(行数&#xff0c;本例为4&#xff09;&#xff0c;按照如下规则打印数字图片 1 5 9 13 2 6 10 14 3 7 11 15 4 8 12 16 以下是使用C语言编写的程序&#xff0c;根据输入的行数打印数字图片的规则&#xff1a; #include <stdio.h>int main() …

深度学习大数据物流平台 python 计算机竞赛

文章目录 0 前言1 课题背景2 物流大数据平台的架构与设计3 智能车货匹配推荐算法的实现**1\. 问题陈述****2\. 算法模型**3\. 模型构建总览 **4 司机标签体系的搭建及算法****1\. 冷启动**2\. LSTM多标签模型算法 5 货运价格预测6 总结7 部分核心代码8 最后 0 前言 &#x1f5…

Spinnaker 基于 docker registry 触发部署

docker registry 触发部署 Spinnaker可以通过Docker镜像的变化来触发部署&#xff0c;这种方法允许你在Docker镜像发生变化时自动启动新的部署流程。 示例原理如下图所示&#xff1a; 以下是如何在Spinnaker中实现基于Docker Registry触发部署的配置流程。最终实现的效果如下…

3D ACIS Modeler和HOOPS Visualize助力鲁班软件打造BIM数字化平台

鲁班软件成立于2001年&#xff0c;始终致力于BIM技术研发和推广&#xff0c;为建筑产业相关企业提供基于BIM技术的数字解决方案&#xff0c;专注打造能够支撑建筑企业集团发展的BIM数字化平台鲁班工程管理数字平台(Luban Builder)&#xff0c;以及可承载园区级或城市级的BIM、C…

NX二次开发UF_CURVE_create_arc_3tangent 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CURVE_create_arc_3tangent Defined in: uf_curve.h int UF_CURVE_create_arc_3tangent(tag_t tangent_object1, tag_t tangent_object2, tag_t tangent_object3, UF_CURVE_help_…

Sass基础知识详细讲解【附带表图】

文章目录 前言使用 SassRack / Rails / Merb插件缓存选项语法选择编码 Sass CSS扩展Sass 注释输出 Sass 脚本Sass -规则和指令Sass 控制指令和表达式 Sass 混入指令Sass 功能指令命名约定Sass 输出样式:nested:expanded:compact:compressedSass 扩展缓存存储自定义导入 后言 前…

算法-技巧-中等-寻找重复数,环形链表|,||

记录一下算法题的学习13 这次代码中运用到的技巧是「Floyd 判圈算法」&#xff08;又称龟兔赛跑算法&#xff09;&#xff0c;它是一个检测链表是否有环的算法 我们想象乌龟tortoise和兔子rabbit在链表上移动&#xff0c;乌龟爬的慢&#xff0c;兔子爬的快&#xff0c;当乌龟和…

芯片技术前沿:了解构现代集成电路的设计与制造

芯片技术前沿:解构现代集成电路的设计与制造 摘要:本文将深入探讨芯片技术的最新进展,重点关注集成电路的设计与制造。我们将带领读者了解芯片设计的基本流程,包括电路分析、版图设计和验证等步骤,并介绍当前主流的制造工艺。此外,我们还将讨论芯片行业面临的挑战以及未…

【腾讯云云上实验室】探索向量数据库背后的安全监控机制

当今数字化时代&#xff0c;数据安全成为了企业和个人最为关注的重要议题之一。随着数据规模的不断增长和数据应用的广泛普及&#xff0c;如何保护数据的安全性和隐私性成为了迫切的需求。 今天&#xff0c;我将带领大家一起探索腾讯云云上实验室所推出的向量数据库&#xff0c…

大电流和大电压谁对人体伤害大

突然想起以前看的这个&#xff0c; 网上有很多解答了这个问题&#xff0c;答案是大电流比大电压对人体伤害大。 我之所以重新来写些&#xff0c; 是想起一种有趣的比喻&#xff0c; 这个答案不绝对。 先看一个场景&#xff0c; 一群牛和一头老虎对你冲来&#xff0c; 谁对你的…

计算机毕业设计|基于SpringBoot+MyBatis框架的电脑商城的设计与实现(用户上传头像+用户收货管理)

计算机毕业设计|基于SpringBootMyBatis框架的电脑商城的设计与实现&#xff08;用户上传头像&#xff09; 该项目分析着重于设计和实现基于SpringBootMyBatis框架的电脑商城。首先&#xff0c;通过深入分析项目所需数据&#xff0c;包括用户、商品、商品类别、收藏、订单、购物…