今天事情有点多,没什么时间刷题,象征性刷几道简单题

lc28. 找出字符串中第一个匹配项的下标(EZ)

给你两个字符串 haystackneedle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1

示例 1:

输入:haystack = "sadbutsad", needle = "sad"
输出:0
解释:"sad" 在下标 0 和 6 处匹配。
第一个匹配项的下标是 0 ,所以返回 0 。

示例 2:

输入:haystack = "leetcode", needle = "leeto"
输出:-1
解释:"leeto" 没有在 "leetcode" 中出现,所以返回 -1 。

提示:

  • 1 <= haystack.length, needle.length <= 10^4
  • haystackneedle 仅由小写英文字符组成

简单的字符串匹配题,甚至不用kmp

轻松ac

class Solution {
public int strStr(String haystack, String needle) {
int n = haystack.length(), m = needle.length();
for (int i = 0; i <= n - m; i++) {
int j = i, k = 0;
while (k < m && haystack.charAt(j) == needle.charAt(k)) {
j++;
k++;
}
if (k == m) {
return i;
}
}
return -1;
}
}

lc125. 验证回文串(EZ)

如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串

字母和数字都属于字母数字字符。

给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false

示例 1:

输入: s = "A man, a plan, a canal: Panama"
输出:true
解释:"amanaplanacanalpanama" 是回文串。

示例 2:

输入:s = "race a car"
输出:false
解释:"raceacar" 不是回文串。

示例 3:

输入:s = " "
输出:true
解释:在移除非字母数字字符之后,s 是一个空字符串 "" 。
由于空字符串正着反着读都一样,所以是回文串。

提示:

  • 1 <= s.length <= 2 * 10^5
  • s 仅由可打印的 ASCII 字符组成

最开始a了一发,结果耗时200ms,非常不满意,遂再写一个时间空间复杂度低一点的

先给我第一个版本的代码

class Solution {
public boolean isPalindrome(String s) {
String para = "";
if (s == "") {
return true;
}
for (int i = 0; i < s.length(); i++) {
if (Character.isLetterOrDigit(s.charAt(i))) {
para += Character.toLowerCase(s.charAt(i));
}
}
int l = 0, r = para.length() - 1;
while (l <= r) {
if (para.charAt(l) != para.charAt(r)) {
return false;
}
l++;
r--;
}
return true;
}
}

这个版本的题解我用了一个String来预处理,也就是说我需要先对给出来的s字符串进行处理之后才能用双指针,这样速度慢了很多

思路不变,但是把这个预处理String的操作优化掉了,直接在原来给定的s上进行指针操作

class Solution {
public boolean isPalindrome(String s) {
if (s == "") {
return true;
}
if (s == null) {
return false;
}
int l = 0, r = s.length() - 1;
while (l <= r) {
while (l < s.length() && !isENCharacter(s.charAt(l))) {
l++;
}
while (r >= 0 && !isENCharacter(s.charAt(r))) {
r--;
}
if (l >= s.length() || r < 0){
return true;
}
if (Character.toLowerCase(s.charAt(l)) != Character.toLowerCase(s.charAt(r))) {
return false;
}
l++;
r--;
}
return true;
}

private boolean isENCharacter(char c) {
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9');
}
}

最后耗时2ms,内存占用41.78mb,非常有成就感


lc392. 判断子序列(EZ)

给定字符串 st ,判断 s 是否为 t 的子序列。

字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace""abcde"的一个子序列,而"aec"不是)。

进阶:

如果有大量输入的 S,称作 S1, S2, … , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?

示例 1:

输入:s = "abc", t = "ahbgdc"
输出:true

示例 2:

输入:s = "axc", t = "ahbgdc"
输出:false

提示:

  • 0 <= s.length <= 100
  • 0 <= t.length <= 10^4
  • 两个字符串都只由小写字符组成。

时间问题,我们不考虑进阶的情况了

难度不大,但我一开始居然没a出来,居然是因为最后判定的时候写错了,操

class Solution {
public boolean isSubsequence(String s, String t) {
if (s == "") {
return true;
}
if (s == null) {
return false;
}
int sp = 0, tp = 0;
while (sp < s.length() && tp < t.length()) {
if (s.charAt(sp) == t.charAt(tp)) {
sp++;
}
tp++;
}
return sp == s.length();
}
}

我wa的第一发就是在 sp == s.length() 这里错的,最开始脑抽写成了s.length() - 1(也许是因为我当时正好在听tymm的歌,沉醉于tymm的歌声不可自拔,遂写错代码犯下低级错误)