算法 —— 模拟

目录

替换所有的问号

提莫攻击

Z字形变换

外观数列


各位读者有听说过"建模"一词吗?所谓"建模",就是把事物进行抽象,根据实际问题来建立对应的数学模型。"抽象"并不意味着晦涩难懂;相反,它提供了大量的便利。计算机很难直接去解决实际问题,但是如果把实际问题建模成数学问题,就会大大地方便计算机来"理解"和"解决"。

举个生活中常见的例子:我们拿到了某次数学考试的成绩单,现在需要知道谁考得最好。当然不能把成绩单对着电脑晃一晃,然后问"谁考得最好?"。需要通过一种途径让计算机来理解这个问题。这个问题可以建模成:"给定数组 score[],问数组内元素的最大值"。这样建模后,就能很方便的写程序解决问题了。对于这个问题,采用之前讨论过的"擂台法",就可以给出答案。


替换所有的问号

cpp 复制代码
class Solution {
public:
	string modifyString(string s) {
		int n = s.size();
		for (int i = 0; i < n; i++)
			if (s[i] == '?')
				for (char c = 'a'; c <= 'z'; c++)
                // 注意边界情况 如果?在首字母或尾字母位置,只需要考虑后面一个字母即可
					if ((i == 0 || s[i - 1] != c) && (i == n - 1 || s[i + 1] != c))
					{
						s[i] = c;
						break;
					}
		return s;
	}
};

提莫攻击

cpp 复制代码
class Solution {
public:
	int findPoisonedDuration(vector<int>& timeSeries, int duration) {
		int n = timeSeries.size(), sum = duration; // 最后一个时刻吃一层满毒
		for (int i = 1; i < n; i++)
		{
			int tmp = timeSeries[i] - timeSeries[i - 1];
			if (tmp >= duration) // 时间差距大于等于中毒时间,意味着吃一层满毒
				sum += duration;
			else   // 时间差距小于中毒时间,意味着时差段中持续中毒
				sum += tmp;
		}
		return sum;
	}
};

Z字形变换

本题可以用两种方法解决,第一种使用模拟,具体操作方法可以阅读蛇形方阵那一篇文章,第二种查找规律,可以发现每一行的元素都与公差存在规律,在找到规律后注意验证。

cpp 复制代码
class Solution {
public:
	string convert(string s, int numRows) {
		string ret;
		if (numRows == 1)
			return s;
		int d = 2 * numRows - 2, n = s.size();
		// 处理第一行
		for (int i = 0; i < n; i+=d)
			ret += s[i];
		// 处理中间行
		for (int k = 1; k < numRows - 1; k++)
		{
			for (int i = k, j = d - k; i < n || j < n; i += d, j += d)
			{
				if (i < n)ret += s[i];
				if (j < n)ret += s[j];
			}
		}
		// 处理最后一行
		for (int i = numRows - 1; i < n; i += d)
			ret += s[i];
		return ret;
	}
};

外观数列

本题首先要理解题目意思:下一行为上一行的读写数字,即第一行是1个1,那么第二行就是11,第三行根据第二行的2个1所以为21......以此类推,代码如下:

cpp 复制代码
class Solution {
public:
	string countAndSay(int n) {
		string ret = "1";
		for (int i = 1; i < n; i++) // 解释 n - 1 次
		{
			string tmp;
			int len = ret.size();
			for (int left = 0, right = 0; right < len;)
			{
				while (right < len && ret[left] == ret[right])
					right++;
				tmp += to_string(right - left) + ret[left];  // right - left为个数 
				left = right;
			}
			ret = tmp;
		}
		return ret;
	}
};
相关推荐
Navigator_Z10 小时前
LeetCode //C - 1317. Convert Integer to the Sum of Two No-Zero Integers
c语言·算法·leetcode
D e re k ZH11 小时前
C++ 标准库算法全景指南
数据结构·c++·算法
冻柠檬飞冰走茶12 小时前
字母移动游戏题解:贪心求最长可保留连续子串(附 C 实现)
c语言·开发语言·数据结构·算法·动态规划
雪落漂泊12 小时前
C++算法 二分查找篇(上)
开发语言·c++·算法
LabVIEW开发14 小时前
LabVIEW 连接板:28 个端子怎么排,优先级怎么定
java·算法·labview
严肃小白兔15 小时前
MATLAB 数值计算中的精度与误差问题:浮点运算、误差传播与数值稳定性
人工智能·算法·matlab
青少儿编程课堂16 小时前
蓝桥杯青少组图形化省考报名倒计时·全国青少年信息素养大赛·电子学会图形化考级:校园黑白棋人机对战解析
c++·python·算法·bfs·信息学竞赛
jktantan17 小时前
注解式脱敏:用 Jackson 的 ContextualSerializer 做字段级策略(一)
spring boot·后端·算法·spring cloud·系统架构
Dream it possible!1 天前
LeetCode 面试经典 150_多维动态规划_交错字符串(97_C++_中等)
算法·leetcode·面试·动态规划