提示:本篇共7道力扣题目供大家食用,时间自行把控~
1、本篇是算法刷题系列文章的第 4
篇,写此系列的目的是为了让自己对题目的理解更加深刻。
2、本系列博客主要参考了卡哥的 代码随想录博客 以及 卡哥本人B站讲解的视频 代码随想录B站视频 ,强烈推荐给大家,因为本人学习中 Python为主
,因此博客主要由 Python
代码呈现给大家,需要其他语言的版本,卡哥博客链接自取。
字符串简单来讲就是一串字符,字符串用双引号引起来,里面的内容几乎包含任何字符,英文字符和中文字符都可以。下面是python里面的字符串创建。
# 第一种
>>> s = str()
>>> s
'' # 空字符
# 第二种
>>> s = "我爱 Python!"
>>> s
# 输出
我爱 Python!
字符串是有序的、不可变的字符集合。可以使用索引方式访问字符串种的任意字符。字符串可以与字符串相加,与整数相乘。
字符串与字符串相加 等于 两个字符串的拼接。
s1 = "Hello,"
s2 = "Python!"
s3 = s1 + s2
print(s3)
# 输出结果
Hello,Python!
字符串与整数 n
相乘 等于 n个
字符串的拼接。代码如下所示。
s1 = "Python"
s2 = s1 * 3
print(s2)
# 输出结果
PythonPythonPython
切片是去部分元素的操作,是 Python
中特有的操作,不仅在字符串中可以使用,列表、元组都支持切片。切片操作有 3
个参数 [start: stop: step]
,其中 start
是切片的起始位置;stop
是切片的终止位置(不包含 stop
);step
代表步长,默认是 1
。代码如下:
>>> s = "abcdefghijk"
>>> s[1:2]
'b'
>>> s[1:10:3]
'beh'
在 Python
中有两种方法遍历字符串:1、根据索引遍历;2、迭代遍历。代码如下:
# 方法一:索引
s = "Hello"
for i in range(len(s)):
print(s[i], end=" ")
##输出
H e l l o
# 方法二:迭代
for i in s:
print(i, end=" ")
##输出
H e l l o
函数 | 语法说明 | 返回值 |
---|---|---|
str.isdigit() | 判断一个字符串是否只含有纯数字 | 若是,返回 True ;否则返回 False |
str.isnumeric() | 判断一个字符串是否只含有纯数字 | 若是,返回 True ;否则返回 False |
str.isalpha() | 判断一个字符串中是否只含有字母 | 若是,返回 True ;否则返回 False |
str.upper() | 将字符串中的小写字母转为大写字母 | 返回全部为大写字母的字符串 |
str.lower() | 将字符串中的大写字母转为小写字母 | 返回全部为小写字母的字符串 |
str.find(str, beg=0, end=len(straing)) | 用于检测字符串中是否包含子字符串str。str:指定检索的字符串;beg:开始索引,默认为0;end:结束索引,默认为字符串的长度 | 如果包含子字符串,则返回开始的索引值,否则返回 -1 |
str.replace(old, new[, max]) | 把字符串中的 old 字符串替换成 new 字符串。old:要被替换的字符串;new:用于替换的新字符串;max:可选,字符串替换不超过 max 次 |
返回替换后的新字符串 |
str.split(str=“”, num=string.count(str)) | 通过指定的 分隔符对字符串进行切分,如果 num 有指定值,则切分成 num+1 个子字符串。str:分隔符,默认是空字符;num:切分次数,默认是 -1 , 即切分所有子字符串 |
返回切分后的字符串列表 |
字符数组 s
的形式给出。注意:你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。left
从前往后遍历字符串,right
从后往前遍历字符串,然后交换 letf
和 right
所指的值,即可在 O(1)
的空间下解决该问题。class Solution:
def reverseString(self, s: List[str]) -> None:
left = 0
right = len(s) - 1
while left < right:
s[left], s[right] = s[right], s[left]
left += 1
right -= 1
给定一个字符串
s
和一个整数k
,从字符串开头算起,每计数至2k
个字符,就反转这2k
字符中的前k
个字符。
- 如果剩余字符少于
k
个,则将剩余字符全部反转;
- 如果剩余字符小于
2k
但大于或等于k
个,则反转前k
个字符,其余字符保持原样。
只要让 i += (2 * k),i 每次移动 2 * k 就可以了
,然后判断是否需要有反转的区间。class Solution:
def reverseStr(self, s: str, k: int) -> str:
def reverse(subString):
left, right = 0, len(subString)-1
while left < right:
subString[left], subString[right] = subString[right], subString[left]
left += 1
right -= 1
return subString
res = list(s)
for i in range(0, len(s), 2*k):
res[i: i+k] = reverse(res[i: i+k])
return ''.join(res)
s
中的每个空格替换成 "%20"
。class Solution:
def replaceSpace(self, s: str) -> str:
res = []
for c in s:
if c == ' ':
res.append("%20")
else:
res.append(c)
return ''.join(res)
- 初始化:空格数量
count
,字符串s
的长度len
;- 统计空格数量:遍历
s
,遇空格则count++
;- 修改
s
长度:添加完"%20"
后的字符串长度应为len + 2 * count
;- 倒序遍历修改:
i
指向原字符串尾部元素,j
指向新字符串尾部元素;当i = j
时跳出(代表左方已没有空格,无需继续遍历);
- 当
s[i]
不为空格时:执行s[j] = s[i]
;
- 当
s[i]
为空格时:将字符串闭区间[j-2, j]
的元素修改为"%20"
;由于修改了3
个元素,因此需要j -= 2
;- 返回值:已修改的字符串
s
;
class Solution:
def replaceSpace(self, s: str) -> str:
counter = s.count(' ')
res = list(s)
# 每碰到一个空格就多拓展两个格子,1 + 2 = 3个位置存’%20‘
res.extend([' '] * counter * 2)
# 原始字符串的末尾,拓展后的末尾
left, right = len(s) - 1, len(res) - 1
while left >= 0:
if res[left] != ' ':
res[right] = res[left]
right -= 1
else:
res[right - 2: right + 1] = '%20'
right -= 3
left -= 1
return ''.join(res)
s
,请你反转字符串中 单词 的顺序。单词 是由非空格字符组成的字符串。s
中使用至少一个空格将字符串中的 单词 分隔开。返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。注意: 输入字符串 s
中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。class Solution:
#1.去除多余的空格
def trim_spaces(self, s):
n = len(s)
left = 0
right = n-1
while left <= right and s[left] == ' ':
left += 1
while left <= right and s[right] == ' ':
right = right-1
tmp = []
while left <= right:
if s[left] != ' ':
tmp.append(s[left])
elif tmp[-1] != ' ':
tmp.append(s[left])
left += 1
return tmp
#2.翻转字符数组
def reverse_string(self, nums, left, right):
while left < right:
nums[left], nums[right] = nums[right], nums[left]
left += 1
right -= 1
return None
#3.翻转每个单词
def reverse_each_word(self, nums):
start = 0
end = 0
n = len(nums)
while start < n:
while end < n and nums[end] != ' ':
end += 1
self.reverse_string(nums, start, end-1)
start = end + 1
end += 1
return None
#4.翻转字符串里的单词
def reverseWords(self, s):
l = self.trim_spaces(s)
self.reverse_string(l, 0, len(l)-1)
self.reverse_each_word(l)
return ''.join(l)
"abcdefg"
和数字 2
,该函数将返回左旋转两位得到的结果 "cdefgab"
。Python
中字符串切片操作,即 return s[n:len(s)] + s[0:n]
语句,便可解决该题。方法二: 局部反转+整体反转实现字符串左旋转操作。具体做法为 --> 1、反转区间为前 n
的子串;2、反转区间为 n
到末尾的子串;3、反转整个字符串。class Solution:
def reverseLeftWords(self, s: str, n: int) -> str:
s = list(s)
# 1、反转区间为前 n 的子串
s[0:n] = list(reversed(s[0:n]))
# 2、反转区间为 n 到末尾的子串;
s[n:] = list(reversed(s[n:]))
# 3、反转整个字符串
s.reverse()
return ''.join(s)
KMP算法
进行求解,具体思路请点击跳转 LeetCode28:找出字符串中第一个匹配项的下标题解之KMP算法 。那篇博客对 KMP算法
进行了详细的阐述,这里不再赘述,只给出参考代码。class Solution:
def strStr(self, haystack: str, needle: str) -> int:
m, n = len(haystack), len(needle)
if n == 0:
return 0
i, j = 0, 0
next = self.getNext(n, needle)
while (i<m and j<n):
if j==-1 or needle[j]==haystack[i]:
i+=1
j+=1
else:
j=next[j]
if j==n:
return i-j
else:
return -1
def getNext(self, n, needle):
next = [' ' for i in range(n)] # next的初始化
j, k = 0, -1
next[0] = k
while (j < n-1 ) :
if k==-1 or needle[k] == needle[j]: # 找到前缀表了
k += 1
j += 1
next[j] = k
else:
k = next[k]
return next
s
,检查是否可以通过由它的一个子串重复多次构成。class Solution:
def repeatedSubstringPattern(self, s: str) -> bool:
if len(s) == 0:
return False
nxt = [0] * len(s)
self.getNext(nxt, s)
if nxt[-1] != -1 and len(s) % (len(s) - (nxt[-1] + 1)) == 0:
return True
return False
def getNext(self, nxt, s):
nxt[0] = -1
j = -1
for i in range(1, len(s)):
while j >= 0 and s[i] != s[j+1]:
j = nxt[j]
if s[i] == s[j+1]:
j += 1
nxt[i] = j
return nxt
字符串篇
到这里就结束了,若文章中有表述不当的地方还望大家多多指出,栈与队列篇
见吧。