浅谈第二阶段刷力扣的体验
浅谈第二阶段刷力扣的体验
一、前言
我陆陆续续刷力扣也有一段时间了,从开始的绞尽脑汁也不会到现在略了解知晓怎么做,但具体做不做的出来还是一个很大问题,还有就是有些算法,数据结构以及思想还未踏进,所以欠缺的还是很多。这里有我现在做题的体会,希望能够分享给大家,以及记录我刷题的经历。
二、题目
给定字符串 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
三、代码过程
class Solution {
public boolean isSubsequence(String s, String t) {
//1.利用暴力 (连续子序列)
//说明:我首先想到的是暴力双循环,但是我在做的过程中不知不觉做成了求解连续子序列问题,
//所以这是我们做题的一个通病:拿到题就开始做,等到代码写的差不多的时候才发现与题目要求
//的不一样。这需要我们认真理解题目。
int m = s.length();
int n = t.length();
if (m > n){
return false;
}
for (int i = 0; i < n - m; i++){
int count = 0;
for (int j = 0; j < m; j++){
if (t.charAt(i + j) == s.charAt(j)){
count++;
}
}
if (count == m){
return true;
}
}
return false;
//2.子序列
//说明:我通过知道上面有问题的时候,才转换成这问题对应的双循环求解。与上面差不多。
int n = t.length();
int m = s.length();
if (m > n) {
return false;
}
int index = 0;
int count = 0;
for (int i = 0; i < m; i++){
for (int j = index; j < n; j++){
if (s.charAt(i) == t.charAt(j)){
count++;
index = j + 1;
break;
}
}
}
if (count == m){
return true;
}
return false;
//3.indexOf()
//说明3:做完后发现,实现效率不高,有没有其他方法降低时间空间复杂度呢?在浏览力扣评论
//的时候(我一般看题解在评论里面找),看见一个代码很干练的,即利用indexOf()java函数,
//时间复杂度大大降低,原因是因为indexOf()采用了KMP算法,有兴趣的可以仔细研究这个
//算法时间复杂度是多少?m ? m + n ? m * n ? 欢迎评论
int index = -1;
for (char c : s.toCharArray()){
index = t.indexOf(c, index + 1);
if (index == -1){
return false;
}
}
return true;
//4.dp
//说明4:我做完暴力我就想到是不是可以用dp动态规划来做,但是动态规划还是比较不容易想的,
//有兴趣可以看看我之前的动态规划讲解,这无疑有是一种解题思路
int m = s.length();
int n = t.length();
int [][]dp = new int[m + 1][n + 1]; //表示s长度为m 的和t长度为n 的相同子序列长度
for (int i = 1; i <= m; i++){
for (int j = 1; j <= n; j++){
if (s.charAt(i - 1) == t.charAt(j - 1)){ //找到字符串s下标为i和字符串t下标为j
//的相同字符
dp[i][j] = dp[i - 1][j - 1] + 1; //找到长度加1
}else{
dp[i][j] = dp[i][j - 1]; //没找到则是原来长度的值
}
}
}
if (dp[m][n] == m){
return true;
}
return false;
}
}
四、总结
作为刚开始刷题的我们来讲,最好的方法就是看人家是怎么做的,然后大致了解实现过程和能够代码敲出来。不需要完全理解这道题后再往下看,因为这样会让你丢失为数不多的耐心和兴趣,然后也是费时费力,强迫理解。度过这一阶段后,就是需要解题联想,一道题有多种算法能够实现,各自的时间空间复杂度也不一样,这就要求我们的知识性扩展性如何了。通常顺序是:暴力->其他算法,有更多的算法实现思维能够帮助我们提高代码的执行效率,找到最优解。
浙公网安备 33010602011771号