算法训练Day9| 28. 实现 strStr();459.重复的子字符串;字符串总结 ;双指针回顾

简介: 算法训练Day9| 28. 实现 strStr();459.重复的子字符串;字符串总结 ;双指针回顾

今日学习的文章链接和视频链接

https://programmercarl.com/0028.%E5%AE%9E%E7%8E%B0strStr.html


LeetCode28.实现strStr()

链接:https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/


1.思路

思路一:两个字符串对象A,B,判断是否A包含B关系。首先判断长度是否满足A>=B,满足则进行继续判断。一个for循环实现对A字符串的遍历,判断首字母是否相同,相同则截取与B字符串等长的A字符串的子串,再来一层for循环遍历判断两字符串是否相同。

思路二:

2.代码实现

 1// 思路一:自己实现运行没通过,思路没问题,应该是边界问题??
 2class Solution {
 3    public int strStr(String haystack, String needle) {
 4        int h = haystack.length();
 5        int n = needle.length();
 6        for (int i = 0; i < h; i++) {
 7            if (h < n) {
 8                return -1;
 9            } else {
10                if (haystack.charAt(i) == needle.charAt(i)) {
11                    // 截取子字符串sub.h
12                    if (i + n >= h) {
13                        return -1;
14
15                    } else {
16                        String sub = haystack.substring(i, i + n);
17                        // 遍历子字符串
18                        int count = 0;
19                        for (int j = 0; j < n; j++) {
20                            if (needle.charAt(j) != sub.charAt(i)) {
21                            break;
22                            } else {
23                                count++;
24                            }
25                        }
26                        if (count == n) {
27                            return i;
28                        }
29                    }
30
31                }
32            }
33
34        }
35
36        return -1;
37    }
38}
39
40// 思路一修正:精简!
41class Solution {
42    public int strStr(String haystack, String needle) {
43        int n = haystack.length(), m = needle.length();
44        for (int i = 0; i + m <= n; i++) { // 原数组边界判定非常巧妙!!!
45            boolean flag = true; // 巧妙的判定方式,get!
46            for (int j = 0; j < m; j++) {
47                if (haystack.charAt(i + j) != needle.charAt(j)) {
48                    flag = false;
49                    break;
50                }
51            }
52            if (flag) {
53                return i;
54            }
55        }
56        return -1;
57    }
58}
59
60// KMP算法抄了一遍
61class Solution {
62    //前缀表(不减一)Java实现
63    public int strStr(String haystack, String needle) {
64        if (needle.length() == 0) return 0;
65        int[] next = new int[needle.length()];
66        getNext(next, needle);
67
68        int j = 0;
69        for (int i = 0; i < haystack.length(); i++) {
70            while (j > 0 && needle.charAt(j) != haystack.charAt(i)) 
71                j = next[j - 1];
72            if (needle.charAt(j) == haystack.charAt(i)) 
73                j++;
74            if (j == needle.length()) 
75                return i - needle.length() + 1;
76        }
77        return -1;
78
79    }
80
81    private void getNext(int[] next, String s) {
82        int j = 0;
83        next[0] = 0;
84        for (int i = 1; i < s.length(); i++) {
85            while (j > 0 && s.charAt(j) != s.charAt(i)) 
86                j = next[j - 1];
87            if (s.charAt(j) == s.charAt(i)) 
88                j++;
89            next[i] = j; 
90        }
91    }
92}

3.复杂度分析

字符串haystack和字符串needle的长度分别是m和n,显然数据量上看,其时间复杂度为O(m * n)

时间复杂度为O(1)


4.思考总结

双层for暴力解决;

滑动窗口处理边界问题容易产生漏洞;

KMP算法的实现逻辑有点抽象,主要是构造next数组的实现细节。


LeetCode459.重复的子字符串

链接:

https://leetcode.cn/problems/repeated-substring-pattern/solution/


1.思路

思路一:for循环遍历,判断是重复段及其段数,对每段再进行滑动窗口的遍历。


2.代码实现

 1// 自己实现,嵌套过多,导致逻辑不清晰。
 2class Solution {
 3    public boolean repeatedSubstringPattern(String s) {
 4        // for循环遍历
 5        int fastIndex = 0;
 6        int SlowIndex = 0;
 7        for (int i = 0; i < s.length(); i++) {
 8            while (s.charAt(SlowIndex) != s.charAt(fastIndex)) {
 9                fastIndex++;
10            }
11            // 相等则进行遍历比较
12            int n = fastIndex;
13            if (s.length() % n != 0) {
14                return false;
15            } else {
16                int m = s.length() / n;
17                boolean bln = true;
18                for (int j = m; j < s.length(); j + m) {
19
20                    if (s.charAt(j - m) != s.charAt(j)) {
21                        return -1;
22                    }
23                }
24                if (bln) {
25                    return ture;
26                }
27            }
28
29        }
30        return false;
31
32
33    }
34}
35
36// 修正思路
37class Solution {
38    public boolean repeatedSubstringPattern(String s) {
39        int n = s.length();
40        // 遍历所有可能的子串长度
41        for (int i = 1; i * 2 <= n; i++) {
42            // 如果字符串长度能够整除当前子串长度
43            if (n % i == 0) {
44                boolean match = true;
45                // 检查从第 i 个字符开始的每个字符是否与前面的子串相等
46                for (int j = i; j < n; j++) {
47                    if (s.charAt(j) != s.charAt(j - i)) {
48                        match = false;
49                        break;
50                    }
51                }
52                // 如果所有字符都与前面的子串相等,则返回 true
53                if (match) {
54                    return true;
55                }
56            }
57        }
58        // 如果没有找到重复的子串,则返回 false
59        return false;
60    }
61}
3.复杂度分析

时间复杂度:O(n²)

空间复杂度:O(1)(不确定)

字符串总结

1.存储形式类似于数组,可以通过索引进行遍历

2.字符串常见问题:

字符串反转:双指针法

字符串包含及重复子串问题:循环遍历(KMP算法进行优化)

今日收获,记录一下自己的学习时长

3h

相关文章
|
3月前
|
算法
【算法】滑动窗口——找到字符串中所有字母异位词
【算法】滑动窗口——找到字符串中所有字母异位词
|
1月前
|
存储 机器学习/深度学习 算法
蓝桥杯练习题(三):Python组之算法训练提高综合五十题
蓝桥杯Python编程练习题的集合,涵盖了从基础到提高的多个算法题目及其解答。
60 3
蓝桥杯练习题(三):Python组之算法训练提高综合五十题
|
18天前
|
分布式计算 Java 开发工具
阿里云MaxCompute-XGBoost on Spark 极限梯度提升算法的分布式训练与模型持久化oss的实现与代码浅析
本文介绍了XGBoost在MaxCompute+OSS架构下模型持久化遇到的问题及其解决方案。首先简要介绍了XGBoost的特点和应用场景,随后详细描述了客户在将XGBoost on Spark任务从HDFS迁移到OSS时遇到的异常情况。通过分析异常堆栈和源代码,发现使用的`nativeBooster.saveModel`方法不支持OSS路径,而使用`write.overwrite().save`方法则能成功保存模型。最后提供了完整的Scala代码示例、Maven配置和提交命令,帮助用户顺利迁移模型存储路径。
|
1月前
|
算法
两个字符串匹配出最长公共子序列算法
本文介绍了最长公共子序列(LCS)问题的算法实现,通过动态规划方法求解两个字符串的最长公共子序列,并提供了具体的编程实现细节和示例。
76 1
两个字符串匹配出最长公共子序列算法
|
1月前
|
机器学习/深度学习 算法 决策智能
【机器学习】揭秘深度学习优化算法:加速训练与提升性能
【机器学习】揭秘深度学习优化算法:加速训练与提升性能
|
1月前
|
算法 Java C++
【贪心算法】算法训练 ALGO-1003 礼物(C/C++)
【贪心算法】算法训练 ALGO-1003 礼物(C/C++)
【贪心算法】算法训练 ALGO-1003 礼物(C/C++)
|
2月前
|
算法 索引 容器
双指针算法详解
本文介绍了双指针算法及其应用。双指针算法是在数组或字符串中常用的高效技术,通过维护两个指针遍历数据结构以解决特定问题。根据指针移动方向,可分为同向双指针、相向双指针和快慢指针。同向双指针如移动零和复写零问题;快慢指针如快乐数问题;相向双指针如盛水最多的容器、有效三角形数量及多数之和等问题。通过合理运用双指针技巧,可简化代码并提高效率。
61 4
双指针算法详解
|
1月前
|
算法 C++
【算法】双指针+二分(C/C++
【算法】双指针+二分(C/C++
|
1月前
|
算法 C++
蓝桥 算法训练 共线(C++)
蓝桥 算法训练 共线(C++)