Tag : 「模拟」、「栈」
给定一个表示代码片段的字符串,你需要实现一个验证器来解析这段代码,并返回它是否合法。合法的代码片段需要遵守以下的所有规则:
合法代码的例子:
xml复制代码输入: "This is the first line "
输出: True
解释:
代码被包含在了闭合的标签内: 和 。
TAG_NAME 是合法的,TAG_CONTENT 包含了一些字符和 cdata 。
即使 CDATA_CONTENT 含有不匹配的起始标签和不合法的 TAG_NAME,它应该被视为普通的文本,而不是标签。
所以 TAG_CONTENT 是合法的,因此代码是合法的。最终返回True。
输入: ">> ![cdata[]] ]]>]]>>]"
输出: True
解释:
我们首先将代码分割为: start_tag|tag_content|end_tag 。
start_tag -> ""
end_tag -> ""
tag_content 也可被分割为: text1|cdata|text2 。
text1 -> ">> ![cdata[]] "
cdata -> "]]>" ,其中 CDATA_CONTENT 为 "]>"
text2 -> "]]>>]"
start_tag 不是 ">>" 的原因参照规则 6 。
cdata 不是 "]]>]]>" 的原因参照规则 7 。
不合法代码的例子:
less复制代码输入: " "
输出: False
解释: 不合法。如果 "" 是闭合的,那么 "" 一定是不匹配的,反之亦然。
输入: " p tag is not closed "
输出: False
输入: " unmatched < "
输出: False
输入: " closed tags with invalid tag name 123 "
输出: False
输入: " unmatched tags with invalid tag name 1234567890> and "
输出: False
输入: " unmatched start tag and unmatched end tag "
输出: False
注意:
字符串大模拟,假设字符串 s 长度为 �n,当前处理到的位置为 �i,根据以下优先级进行检查:
最后由于整个 s 应当被一对 TAG_NAME 所包裹,因此当 �=0i=0 时,不能是情况 11 和情况 33,需要特判一下。
代码:
Java复制代码class Solution {
String CDATA1 = "";
public boolean isValid(String s) {
Deque d = new ArrayDeque<>();
int n = s.length(), i = 0;
while (i < n) {
if (i + 8 < n && s.substring(i, i + 9).equals(CDATA1)) {
if (i == 0) return false;
int j = i + 9;
boolean ok = false;
while (j < n && !ok) {
if (j + 2 < n && s.substring(j, j + 3).equals(CDATA2)) {
j = j + 3; ok = true;
} else {
j++;
}
}
if (!ok) return false;
i = j;
} else if (s.charAt(i) == '<') {
if (i == n - 1) return false;
boolean isEnd = s.charAt(i + 1) == '/';
int p = isEnd ? i + 2 : i + 1, j = p;
while (j < n && s.charAt(j) != '>') {
if (!Character.isUpperCase(s.charAt(j))) return false;
j++;
}
if (j == n) return false;
int len = j - p;
if (len < 1 || len > 9) return false;
String tag = s.substring(p, j);
i = j + 1;
if (!isEnd) {
d.addLast(tag);
} else {
if (d.isEmpty() || !d.pollLast().equals(tag)) return false;
if (d.isEmpty() && i < n) return false;
}
} else {
if (i == 0) return false;
i++;
}
}
return d.isEmpty();
}
}
这是我们「刷穿 LeetCode」系列文章的第 No.591 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:github.com/SharingSour… 。
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
页面更新:2024-04-18
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号