代码随想录算法训练营第九天 | 字符串part02

代码随想录算法训练营第九天 | 字符串part02

151 翻转字符串里的单词

image.png

举个例子,源字符串为:"the sky is blue "

  • 移除多余空格 : "the sky is blue"
  • 字符串反转:"eulb si yks eht"
  • 单词反转:"blue is sky the"

(版本一)先删除空白,然后整个反转,最后单词反转。 因为字符串是不可变类型,所以反转单词的时候,需要将其转换成列表,然后通过join函数再将其转换成列表,所以空间复杂度不是O(1)

# 删除前后空白
s = s.strip()
# 反转整个字符串
s = s[::-1]
# 将字符串拆分为单词,并反转每个单词
s = ' '.join(word[::-1] for word in s.split())
return s

(版本二)使用双指针

# 将字符串拆分为单词,即转换成列表类型
words = s.split()
# 反转单词
left, right = 0, len(words) - 1
while left < right:
    words[left], words[right] = words[right], words[left]
    left += 1
    right -= 1
# 将列表转换成字符串
return " ".join(words)

(版本三) 拆分字符串 + 反转列表

words = s.split() #type(words) --- list
words = words[::-1] # 反转单词
return ' '.join(words) #列表转换成字符串

卡码网:55 右旋转字符串

image.png

本人思路

因为是右边的挪到了前面,所以先在前面补充几个0,然后和最后的几个换位置就可以了。

s = "abcdefg"
n = 2
s_ = [0] * n
s_.extend(s)
left = 0
right = len(s_) - n
while left < n:
    s_[left] , s_[right] = s_[right] , s_[left]
    left += 1
    right += 1
list_ = []
for i in range(len(s_)):
    if s_[i] != 0:
        list_.append(s_[i])
print(''.join(list_))

答案方法

#获取输入的数字k和字符串
k = int(input())
s = input()
​
#通过切片反转第一段和第二段字符串
#注意:python中字符串是不可变的,所以也需要额外空间
s = s[len(s)-k:] + s[:len(s)-k]
print(s)
k = int(input())
s = input()
​
print(s[-k:] + s[:-k])

28 实现 strStr() (本题可以跳过)

image.png

自己做的,思路很简单,就是对比,这个对比首先对比头,然后对比尾,每次尾--

haystack = "a"
needle = "a"
n = len(needle) - 1
left = 0
right = left + n
list_ = []
print(left,right,n)
if len(needle) == 1:
    for i in range(len(haystack)):
        if haystack[i] == needle[0]:
            print(i)
while left < right and left <= (len(haystack) - len(needle)):
    while left < right and haystack[left] == needle[0] and haystack[right] == needle[n]:
        right -= 1
        n -= 1
        print(left,right,n)
        if left == right:
            list_.append(left)
    n = len(needle) - 1
    left += 1
    right = left + n
​
if len(list_) > 1:
    print(list_[0])
else:
    print(-1)

暴力法

m, n = len(haystack), len(needle)
for i in range(m):
    if haystack[i:i+n] == needle:
        return i
return -1    

使用 index

try:
    return haystack.index(needle)
except ValueError:
    return -1

使用 find

return haystack.find(needle)

前缀表(-1)

def getNext(self, next, s):
    j = -1
    next[0] = j
    for i in range(1, len(s)):
        while j >= 0 and s[i] != s[j+1]:
            j = next[j]
        if s[i] == s[j+1]:
            j += 1
        next[i] = j
​
def strStr(self, haystack: str, needle: str) -> int:
    if not needle:
        return 0
    next = [0] * len(needle)
    self.getNext(next, needle)
    j = -1
    for i in range(len(haystack)):
        while j >= 0 and haystack[i] != needle[j+1]:
            j = next[j]
        if haystack[i] == needle[j+1]:
            j += 1
        if j == len(needle) - 1:
            return i - len(needle) + 1
    return -1

前缀表(不-1)

def getNext(self, next: List[int], s: str) -> None:
    j = 0
    next[0] = 0
    for i in range(1, len(s)):
        while j > 0 and s[i] != s[j]:
            j = next[j - 1]
        if s[i] == s[j]:
            j += 1
        next[i] = j
​
def strStr(self, haystack: str, needle: str) -> int:
    if len(needle) == 0:
        return 0
    next = [0] * len(needle)
    self.getNext(next, needle)
    j = 0
    for i in range(len(haystack)):
        while j > 0 and haystack[i] != needle[j]:
            j = next[j - 1]
        if haystack[i] == needle[j]:
            j += 1
        if j == len(needle):
            return i - len(needle) + 1
    return -1

459 重复的子字符串 (本题可以跳过)

image.png

(版本一) 前缀表 减一

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

(版本二) 前缀表 不减一

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] != 0 and len(s) % (len(s) - nxt[-1]) == 0:
            return True
        return False
    
    def getNext(self, nxt, s):
        nxt[0] = 0
        j = 0
        for i in range(1, len(s)):
            while j > 0 and s[i] != s[j]:
                j = nxt[j - 1]
            if s[i] == s[j]:
                j += 1
            nxt[i] = j
        return nxt

(版本三) 使用 find

class Solution:
    def repeatedSubstringPattern(self, s: str) -> bool:
        n = len(s)
        if n <= 1:
            return False
        ss = s[1:] + s[:-1] 
        print(ss.find(s))              
        return ss.find(s) != -1

(版本四) 暴力法

class Solution:
    def repeatedSubstringPattern(self, s: str) -> bool:
        n = len(s)
        if n <= 1:
            return False
        
        substr = ""
        for i in range(1, n//2 + 1):
            if n % i == 0:
                substr = s[:i]
                if substr * (n//i) == s:
                    return True
                
        return False