99>
1010> 原文地址:https://www.weiweiblog.cn/13string/
1111
12-
1312## 1. KMP 算法
1413
15- 谈到字符串问题,不得不提的就是 KMP 算法,它是用来解决字符串查找的问题,可以在一个字符串(S)中查找一个子串(W)出现的位置。KMP 算法把字符匹配的时间复杂度缩小到 O(m+n) ,而空间复杂度也只有O (m)。因为“暴力搜索”的方法会反复回溯主串,导致效率低下,而KMP算法可以利用已经部分匹配这个有效信息 ,保持主串上的指针不回溯,通过修改子串的指针,让模式串尽量地移动到有效的位置。
14+ 谈到字符串问题,不得不提的就是 KMP 算法,它是用来解决字符串查找的问题,可以在一个字符串(S)中查找一个子串(W)出现的位置。KMP 算法把字符匹配的时间复杂度缩小到 O(m+n) ,而空间复杂度也只有 O (m)。因为“暴力搜索”的方法会反复回溯主串,导致效率低下,而 KMP 算法可以利用已经部分匹配这个有效信息 ,保持主串上的指针不回溯,通过修改子串的指针,让模式串尽量地移动到有效的位置。
1615
1716具体算法细节请参考:
1817
19- - ** 字符串匹配的KMP算法:** http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html
20- - ** 从头到尾彻底理解KMP:** https://blog.csdn.net/v_july_v/article/details/7041827
21- - ** 如何更好的理解和掌握 KMP 算法?:** https://www.zhihu.com/question/21923021
22- - ** KMP 算法详细解析:** https://blog.sengxian.com/algorithms/kmp
23- - ** 图解 KMP 算法:** http://blog.jobbole.com/76611/
24- - ** 汪都能听懂的KMP字符串匹配算法【双语字幕】:** https://www.bilibili.com/video/av3246487/?from=search&seid=17173603269940723925
25- - ** KMP字符串匹配算法1:** https://www.bilibili.com/video/av11866460?from=search&seid=12730654434238709250
26-
27- ** 除此之外,再来了解一下BM算法!**
18+ - [ 从头到尾彻底理解 KMP:] ( https://blog.csdn.net/v_july_v/article/details/7041827 )
19+ - [ 如何更好的理解和掌握 KMP 算法?] ( https://www.zhihu.com/question/21923021 )
20+ - [ KMP 算法详细解析] ( https://blog.sengxian.com/algorithms/kmp )
21+ - [ 图解 KMP 算法] ( http://blog.jobbole.com/76611/ )
22+ - [ 汪都能听懂的 KMP 字符串匹配算法【双语字幕】] ( https://www.bilibili.com/video/av3246487/?from=search&seid=17173603269940723925 )
23+ - [ KMP 字符串匹配算法 1] ( https://www.bilibili.com/video/av11866460?from=search&seid=12730654434238709250 )
2824
29- > BM算法也是一种精确字符串匹配算法,它采用从右向左比较的方法,同时应用到了两种启发式规则,即坏字符规则 和好后缀规则 ,来决定向右跳跃的距离。基本思路就是从右往左进行字符匹配,遇到不匹配的字符后从坏字符表和好后缀表找一个最大的右移值,将模式串右移继续匹配。
30- 《字符串匹配的KMP算法》:http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html
25+ ** 除此之外,再来了解一下 BM 算法!**
3126
27+ > BM 算法也是一种精确字符串匹配算法,它采用从右向左比较的方法,同时应用到了两种启发式规则,即坏字符规则 和好后缀规则 ,来决定向右跳跃的距离。基本思路就是从右往左进行字符匹配,遇到不匹配的字符后从坏字符表和好后缀表找一个最大的右移值,将模式串右移继续匹配。
28+ > 《字符串匹配的 KMP 算法》:http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html
3229
3330## 2. 替换空格
3431
35- > 剑指offer :请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We %20Are%20Happy。
32+ > 剑指 offer :请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为 We Are Happy.则经过替换之后的字符串为 We %20Are%20Happy。
3633
37- 这里我提供了两种方法:①常规方法;②利用 API 解决。
34+ 这里我提供了两种方法:① 常规方法;② 利用 API 解决。
3835
3936``` java
4037// https://www.weiweiblog.cn/replacespace/
@@ -65,7 +62,7 @@ public class Solution {
6562 * 第二种方法:利用API替换掉所用空格,一行代码解决问题
6663 */
6764 public static String replaceSpace2 (StringBuffer str ) {
68-
65+
6966 return str. toString(). replaceAll(" \\ s" , " %20" );
7067 }
7168}
@@ -80,7 +77,7 @@ str.toString().replace(" ","%20");
8077
8178## 3. 最长公共前缀
8279
83- > Leetcode: 编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 ""。
80+ > Leetcode: 编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 ""。
8481
8582示例 1:
8683
@@ -97,8 +94,7 @@ str.toString().replace(" ","%20");
9794解释: 输入不存在公共前缀。
9895```
9996
100-
101- 思路很简单!先利用Arrays.sort(strs)为数组排序,再将数组第一个元素和最后一个元素的字符从前往后对比即可!
97+ 思路很简单!先利用 Arrays.sort(strs)为数组排序,再将数组第一个元素和最后一个元素的字符从前往后对比即可!
10298
10399``` java
104100public class Main {
@@ -160,12 +156,10 @@ public class Main {
160156
161157### 4.1. 最长回文串
162158
163- > LeetCode: 给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。在构造过程中,请注意区分大小写。比如` "Aa" ` 不能当做一个回文字符串。注
164- 意:假设字符串的长度不会超过 1010。
165-
166-
159+ > LeetCode: 给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。在构造过程中,请注意区分大小写。比如` "Aa" ` 不能当做一个回文字符串。注
160+ > 意:假设字符串的长度不会超过 1010。
167161
168- > 回文串:“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。——百度百科 地址:https://baike.baidu.com/item/%E5%9B%9E%E6%96%87%E4%B8%B2/1274921?fr=aladdin
162+ > 回文串:“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。——百度百科 地址:https://baike.baidu.com/item/%E5%9B%9E%E6%96%87%E4%B8%B2/1274921?fr=aladdin
169163
170164示例 1:
171165
@@ -185,7 +179,7 @@ public class Main {
185179- 字符出现次数为双数的组合
186180- ** 字符出现次数为偶数的组合+单个字符中出现次数最多且为奇数次的字符** (参见 ** [ issue665] ( https://github.com/Snailclimb/JavaGuide/issues/665 ) ** )
187181
188- 统计字符出现的次数即可,双数才能构成回文。因为允许中间一个数单独出现,比如“abcba”,所以如果最后有字母落单,总长度可以加 1。首先将字符串转变为字符数组。然后遍历该数组,判断对应字符是否在hashset中 ,如果不在就加进去,如果在就让count ++,然后移除该字符!这样就能找到出现次数为双数的字符个数。
182+ 统计字符出现的次数即可,双数才能构成回文。因为允许中间一个数单独出现,比如“abcba”,所以如果最后有字母落单,总长度可以加 1。首先将字符串转变为字符数组。然后遍历该数组,判断对应字符是否在 hashset 中 ,如果不在就加进去,如果在就让 count ++,然后移除该字符!这样就能找到出现次数为双数的字符个数。
189183
190184``` java
191185// https://leetcode-cn.com/problems/longest-palindrome/description/
@@ -210,7 +204,6 @@ class Solution {
210204}
211205```
212206
213-
214207### 4.2. 验证回文串
215208
216209> LeetCode: 给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。 说明:本题中,我们将空字符串定义为有效的回文串。
@@ -255,10 +248,9 @@ class Solution {
255248}
256249```
257250
258-
259251### 4.3. 最长回文子串
260252
261- > Leetcode: LeetCode: 最长回文子串 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为1000 。
253+ > Leetcode: LeetCode: 最长回文子串 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000 。
262254
263255示例 1:
264256
@@ -308,10 +300,10 @@ class Solution {
308300### 4.4. 最长回文子序列
309301
310302> LeetCode: 最长回文子序列
311- 给定一个字符串s ,找到其中最长的回文子序列。可以假设s的最大长度为1000 。
312- ** 最长回文子序列和上一题最长回文子串的区别是,子串是字符串中连续的一个序列,而子序列是字符串中保持相对位置的字符序列,例如,"bbbb"可以是字符串"bbbab"的子序列但不是子串。**
303+ > 给定一个字符串 s ,找到其中最长的回文子序列。可以假设 s 的最大长度为 1000 。
304+ > ** 最长回文子序列和上一题最长回文子串的区别是,子串是字符串中连续的一个序列,而子序列是字符串中保持相对位置的字符序列,例如,"bbbb"可以是字符串"bbbab"的子序列但不是子串。**
313305
314- 给定一个字符串s ,找到其中最长的回文子序列。可以假设s的最大长度为1000 。
306+ 给定一个字符串 s ,找到其中最长的回文子序列。可以假设 s 的最大长度为 1000 。
315307
316308示例 1:
317309
@@ -321,6 +313,7 @@ class Solution {
321313输出:
3223144
323315```
316+
324317一个可能的最长回文子序列为 "bbbb"。
325318
326319示例 2:
@@ -334,7 +327,7 @@ class Solution {
334327
335328一个可能的最长回文子序列为 "bb"。
336329
337- ** 动态规划:** dp[ i] [ j ] = dp[ i+1] [ j-1 ] + 2 if s.charAt(i) == s.charAt(j) otherwise, dp[ i] [ j ] = Math.max(dp[ i+1] [ j ] , dp[ i] [ j-1 ] )
330+ ** 动态规划:** dp[ i] [ j ] = dp[ i+1] [ j-1 ] + 2 if s.charAt(i) == s.charAt(j) otherwise, dp[ i] [ j ] = Math.max(dp[ i+1] [ j ] , dp[ i] [ j-1 ] )
338331
339332``` java
340333class Solution {
@@ -358,19 +351,21 @@ class Solution {
358351## 5. 括号匹配深度
359352
360353> 爱奇艺 2018 秋招 Java:
361- > 一个合法的括号匹配序列有以下定义:
362- > 1 . 空串""是一个合法的括号匹配序列
363- > 2 . 如果"X"和"Y"都是合法的括号匹配序列,"XY"也是一个合法的括号匹配序列
364- > 3 . 如果"X"是一个合法的括号匹配序列,那么"(X)"也是一个合法的括号匹配序列
365- > 4 . 每个合法的括号序列都可以由以上规则生成。
354+ > 一个合法的括号匹配序列有以下定义:
355+ >
356+ > 1 . 空串""是一个合法的括号匹配序列
357+ > 2 . 如果"X"和"Y"都是合法的括号匹配序列,"XY"也是一个合法的括号匹配序列
358+ > 3 . 如果"X"是一个合法的括号匹配序列,那么"(X)"也是一个合法的括号匹配序列
359+ > 4 . 每个合法的括号序列都可以由以上规则生成。
366360
367361> 例如: "","()","()()","((()))"都是合法的括号序列
368- > 对于一个合法的括号序列我们又有以下定义它的深度:
369- > 1 . 空串""的深度是0
370- > 2 . 如果字符串"X"的深度是x,字符串"Y"的深度是y,那么字符串"XY"的深度为max(x,y)
371- > 3 . 如果"X"的深度是x,那么字符串"(X)"的深度是x+1
362+ > 对于一个合法的括号序列我们又有以下定义它的深度:
363+ >
364+ > 1 . 空串""的深度是 0
365+ > 2 . 如果字符串"X"的深度是 x,字符串"Y"的深度是 y,那么字符串"XY"的深度为 max(x,y)
366+ > 3 . 如果"X"的深度是 x,那么字符串"(X)"的深度是 x+1
372367
373- > 例如: "()()()"的深度是1 ,"((()))"的深度是3 。牛牛现在给你一个合法的括号序列,需要你计算出其深度。
368+ > 例如: "()()()"的深度是 1 ,"((()))"的深度是 3 。牛牛现在给你一个合法的括号序列,需要你计算出其深度。
374369
375370```
376371输入描述:
@@ -396,7 +391,7 @@ import java.util.Scanner;
396391
397392/**
398393 * https://www.nowcoder.com/test/8246651/summary
399- *
394+ *
400395 * @author Snailclimb
401396 * @date 2018年9月6日
402397 * @Description: TODO 求给定合法括号序列的深度
@@ -422,7 +417,7 @@ public class Main {
422417
423418## 6. 把字符串转换成整数
424419
425- > 剑指offer: 将一个字符串转换成一个整数(实现Integer .valueOf(string)的功能,但是string不符合数字要求时返回0 ),要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0 。
420+ > 剑指 offer: 将一个字符串转换成一个整数(实现 Integer .valueOf(string)的功能,但是 string 不符合数字要求时返回 0 ),要求不能使用字符串转换整数的库函数。 数值为 0 或者字符串不是一个合法的数值则返回 0 。
426421
427422``` java
428423// https://www.weiweiblog.cn/strtoint/
0 commit comments