持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情
LeetCode 75 学习计划适用于想为技术面试做准备但不确定应该聚焦于哪些题目的用户。学习计划中的题目都是经过精心挑选的,Level 1和 Level 2 学习计划是为初级用户和中级用户准备的,题目覆盖了大多数中层公司面试时所必需的数据结构和算法,Level 3 学习计划则是为准备面试顶级公司的用户准备的。来源
第 2 天
判断子序列
难度:简单
题目
给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。
进阶:
如果有大量输入的 S,称作 S1, S2, ... , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?
示例 1:
输入:s = "abc", t = "ahbgdc"
输出:true
示例 2:
输入:s = "axc", t = "ahbgdc"
输出:false
解答
这题怎么看起来,感觉和上题目有点像呢?
难道也是双 Map 解答吗?
假设例子是 “abcde”
问子序列 “ace” 是不是
设 s2 为第一个 map
key 是 abcde 的 项,value 是 ace 的项,判断 abcde 项是否在 ace 中。
{a:a,b:c,c:e,d:0,e:0}
设 t2 为第二个 map
key 是 ace 的项,value 是 abcde 的项,判断 ace 的项是否在 abcde 中。
{a:a,c:b,e:c}
因为是依次序的!!
如果是 aec 呢?
s2 = {a:a,b:e,c:c,d:0,e:0}
t2 = {a:a,e:b,c:c}
如果是 axc 呢?
s2 = {a:a,b:x,c:c,d:0,e:0}
t2 = {a:a,x:b,c:c}
这两种是不符合要求的,应该返回 flase;
当 t2 的某一项 key,s2[key] === 0 的时候,必须是最后一项才行。如果不是,则返回 false
解:
/**
* @param {string} s
* @param {string} t
* @return {boolean}
*/
var isSubsequence = function(s, t) {
let s2 = new Map()
let t2 = nwe Map()
let arr = s.split("")
for(let i = 0;i<arr.length;i++){
if(s2[i]===0&&???)
....
}
return true
};
根本不行啊,看题解用双指针豁然开朗。
两个指针分别指向两个字符串,如果相同,就往前移动一位,如果不同,则,长的串继续移动,直至 长的 遍历完,此时看 短的是否遍历完,如果没有,则 false,反之 true
/**
* @param {string} s
* @param {string} t
* @return {boolean}
*/
var isSubsequence = function(s, t) {
if (s.split("").length == 0) return true;
for (let i = 0, j = 0; j < t.split("").length; j++) {
if (s.split("")[i]== t.split("")[j]) {
// 若已经遍历完 s ,则提前返回 true
if (++i == s.split("").length)
return true;
}
}
return false;
};
或者更简洁的做法:
/**
* @param {string} s
* @param {string} t
* @return {boolean}
*/
var isSubsequence = function(s, t) {
if(s==="") return true
let p0 = 0
let p1 = 0
while(p1<t.length){
if(s[p0]===t[p1]){
p0++
}
if(p0===s.length){
return true
}
p1++
}
return false
};
总结
是双 map 还是双指针,要仔细想想。
不服不行,看看题解,一下就懂。。。