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

LeetCode 1003. Check If Word Is Valid After Substitutions【栈,字符串】中等

本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章中,我不仅会讲解多种解题思路及其优化,还会用多种编程语言实现题解,涉及到通用解法时更将归纳总结出相应的算法模板。

为了方便在PC上运行调试、分享代码文件,我还建立了相关的仓库:https://github.com/memcpy0/LeetCode-Conquest。在这一仓库中,你不仅可以看到LeetCode原题链接、题解代码、题解文章链接、同类题目归纳、通用解法总结等,还可以看到原题出现频率和相关企业等重要信息。如果有其他优选题解,还可以一同分享给他人。

由于本系列文章的内容随时可能发生更新变动,欢迎关注和收藏征服LeetCode系列文章目录一文以作备忘。

给你一个字符串 s ,请你判断它是否 有效 。字符串 s 有效 需要满足:假设开始有一个空字符串 t = "" ,你可以执行 任意次 下述操作将 t 转换为 s

  • 将字符串 "abc" 插入到 t 中的任意位置。形式上,t 变为 tleft + "abc" + tright,其中 t == tleft + tright 。注意,tlefttright 可能为

如果字符串 s 有效,则返回 true;否则,返回 false

示例 1:

Input: s = "aabcbc"
Output: true
Explanation:
"" -> "abc" -> "aabcbc"
Thus, "aabcbc" is valid.

示例 2:

Input: s = "abcabcababcc"
Output: true
Explanation:
"" -> "abc" -> "abcabc" -> "abcabcabc" -> "abcabcababcc"
Thus, "abcabcababcc" is valid.

示例 3:

Input: s = "abccba"
Output: false
Explanation: It is impossible to get "abccba" using the operation.

提示:

  • 1 <= s.length <= 2 * 10^4
  • s 由字母 'a''b''c' 组成

解法1 暴力

本题与20. 有效的括号类似,如果把问题改成「将字符串 (), [], {} 插入到 t t t 中的任意位置」,比如 () -> ([] -> ([]{}) ,根据「是否可用这种方式获得字符串 s s s 」来判断字符串有效,就完全一致了。

这里最简单的做法是逆向转换,不断从字符串中删除加入的 a b c abc abc 、最后删成空,就能返回 true

class Solution {
public:
    bool isValid(string s) {
        size_t pos;
        while ((pos = s.find("abc")) != string::npos)
            s.erase(pos, 3);
        return s.empty();
    }
};

解法2 栈

解法1复杂度高,于是想到了栈。20. 有效的括号也是用栈解决的:左括号入栈,对于右括号去判断栈顶是否为其匹配的左括号,匹配就让左括号出栈,否则返回 false 。本题也可用类似的方法完成:

  • 字符 a {a} a :类似左括号,直接入栈。
  • 字符 b {b} b如果栈为空,或者栈顶不为 a {a} a ,则返回 false ,否则将栈顶修改为 b {b} b(或者出栈再入栈)。
  • 字符 c {c} c如果栈为空,或者栈顶不为 b {b} b ,则返回 false ,否则弹出栈顶,相当于找到了一个 a b c {abc} abc
  • 代码实现时, b {b} b c {c} c 的逻辑可以合并在一起, a {a} a b {b} b 的入栈逻辑可以合并在一起。
  • 循环结束后,如果栈为空,则返回 true ,否则返回 false

一个合适的比喻是消消乐。比如 ab abc c ,中间的 abc 消除后,c 从后面滑到前面、撞击前面的 ab 、再次消除。

class Solution {
public: 
	bool isValid(string s) { // s同时作为栈
		int i = 0; // i-1表示栈顶下标,i=0表示栈为空
		for (char c : s) {
			if (c > 'a' && (i == 0 || c - s[--i] != 1))
				return false;
			if (c < 'c') s[i++] = c; // 入栈
		}
		return i == 0;
	}
};

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n) ,其中 n n n s s s 的长度。
  • 空间复杂度: O ( n ) O(n) O(n) O ( 1 ) O(1) O(1) 。如果可以直接修改字符串(例如C++),那么只需 O ( 1 ) O(1) O(1) 的额外空间。

http://www.kler.cn/a/17414.html

相关文章:

  • SpringMVC学习笔记(二)
  • 基于海思soc的智能产品开发(两个图像处理来源)
  • 深入探索React合成事件(SyntheticEvent):跨浏览器的事件处理利器
  • Mysql数据库里的SSH连接
  • 基于碎纸片的拼接复原算法及MATLAB实现
  • SpringBoot参数注解
  • 【GAMES101】03 Transformation
  • 回忆我的爷爷
  • 什么是图数据库Neo4j
  • 力扣---LeetCode141/142. 环形链表 (I)和(II) (代码详解+流程图+数学逻辑拓展)
  • 自动驾驶技术:前景、优势与挑战
  • kubernetes安装
  • Docker 架构
  • Vue生命周期
  • 第二十四回:如何屏蔽事件
  • SpringMVC(后)SSM整合
  • [创新工具和方法论]-01- DOE课程基础知识
  • K8s 安全是云安全的未来
  • AI仿写软件-仿写文章生成器
  • 计算机组成原理4.2.3提高存储器访问速度的措施
  • 送了老弟一台 Linux 服务器,它又懵了!
  • Ae:橡皮擦工具
  • Redis缓存穿透和雪崩
  • 3 文件和目录
  • 归纳截图小结
  • innodb_flush_log_at_trx_commit 和 sync_binlog 参数解析