串是編程中最常用的數據結構之一,從簡單的文本處理到復雜的文本匹配算法,串的應用無處不在。在掌握了串的基本概念、存儲結構以及KMP算法之后,現在讓我們深入探索串的更多高級操作,例如求子串、串的替換等,并通過LeetCode上的題目實戰訓練來進一步提升我們對串的處理能力。
?
一、串的高級操作
(一)求子串
概念 :從一個較長的字符串中提取一個連續的部分作為子串。例如,“hello world” 的子串可以是 “hello”、“world”、“lo wo” 等。
?
Python 實現 :在Python中,求子串非常簡單,可以通過切片操作來實現。
python
def get_substring(s, start, length):
? ? return s[start:start + length]
?
# 示例
text = "hello world"
substring = get_substring(text, 6, 5) # 提取 "world"
print(substring) # 輸出: world
?
(二)串的替換
概念 :在一個字符串中查找特定的子串,并將其替換為另一個字符串。例如,將字符串 "hello world" 中的 "world" 替換為 "everyone",結果為 "hello everyone"。
?
Python 實現 :Python 的 `str.replace()` 方法提供了強大的替換功能。
python
def replace_substring(s, old, new):
? ? return s.replace(old, new)
?
# 示例
text = "hello world"
new_text = replace_substring(text, "world", "everyone")
print(new_text) # 輸出: hello everyone
?
(三)字符串反轉
概念 :將字符串中的字符順序完全顛倒。例如,“hello” 反轉后變為 “olleh”。
?
Python 實現 :可以通過切片操作或 `reversed` 函數來實現。
python
def reverse_string(s):
? ? return s[::-1]
?
# 或者
def reverse_string(s):
? ? return ''.join(reversed(s))
?
# 示例
text = "hello"
reversed_text = reverse_string(text)
print(reversed_text) # 輸出: olleh
?
(四)字符串去重
概念 :去除字符串中的重復字符,只保留第一次出現的字符。例如,“abcabc” 去重后變為 “abc”。
?
Python 實現 :可以使用集合來記錄已經出現過的字符。
python
def remove_duplicates(s):
? ? seen = set()
? ? result = []
? ? for char in s:
? ? ? ? if char not in seen:
? ? ? ? ? ? seen.add(char)
? ? ? ? ? ? result.append(char)
? ? return ''.join(result)
?
# 示例
text = "abcabc"
unique_text = remove_duplicates(text)
print(unique_text) # 輸出: abc
?
二、LeetCode 實戰題目訓練
(一)【題目】:無重復字符的最長子串(LeetCode 3)
題目描述 :給定一個字符串,找出其中不含有重復字符的最長子串的長度。
?
解題思路 :使用滑動窗口技術。用兩個指針表示一個窗口的左右邊界,移動右邊界擴展窗口,當遇到重復字符時,移動左邊界收縮窗口。同時維護一個集合記錄窗口內的字符,以及一個變量記錄最長無重復子串的長度。
?
Python 實現 :
def length_of_longest_substring(s):
? ? char_set = set()
? ? left = 0
? ? max_length = 0
? ? for right in range(len(s)):
? ? ? ? while s[right] in char_set:
? ? ? ? ? ? char_set.remove(s[left])
? ? ? ? ? ? left += 1
? ? ? ? char_set.add(s[right])
? ? ? ? max_length = max(max_length, right - left + 1)
? ? return max_length
?
# 示例
text = "abcabcbb"
print(length_of_longest_substring(text)) # 輸出: 3
?
(二)【題目】:字符串中的第一個唯一字符(LeetCode 387)
?
題目描述 :給定一個字符串,找到第一個不重復的字符,并返回其在字符串中的位置。如果不存在,則返回 -1。
?
解題思路 :可以使用哈希表統計每個字符的出現次數,然后再次遍歷字符串找到第一個出現次數為1的字符的位置。
?
Python 實現 :
def first_uniq_char(s):
? ? char_count = {}
? ? for char in s:
? ? ? ? char_count[char] = char_count.get(char, 0) + 1
? ? for index, char in enumerate(s):
? ? ? ? if char_count[char] == 1:
? ? ? ? ? ? return index
? ? return -1
?
# 示例
text = "leetcode"
print(first_uniq_char(text)) # 輸出: 0
?
(三)【題目】:字符串的排列(LeetCode 567)
?
題目描述 :給定兩個字符串 s1 和 s2,寫一個函數來判斷 s2 是否包含 s1 的排列。換句話說,第一個字符串的排列之一是第二個字符串的子串。
?
解題思路 :使用滑動窗口和哈希表來解決。維護一個窗口,使窗口內的字符計數與 s1 的字符計數相匹配。如果匹配成功,則 s2 包含 s1 的排列。
?
Python 實現 :
def check_inclusion(s1, s2):
? ? from collections import Counter
? ? len1, len2 = len(s1), len(s2)
? ? if len1 > len2:
? ? ? ? return False
? ? counter1 = Counter(s1)
? ? counter2 = Counter(s2[:len1])
? ? if counter1 == counter2:
? ? ? ? return True
? ? for i in range(len1, len2):
? ? ? ? counter2[s2[i]] += 1
? ? ? ? counter2[s2[i - len1]] -= 1
? ? ? ? if counter2[s2[i - len1]] == 0:
? ? ? ? ? ? del counter2[s2[i - len1]]
? ? ? ? if counter1 == counter2:
? ? ? ? ? ? return True
? ? return False
?
# 示例
s1 = "ab"
s2 = "eidbaooo"
print(check_inclusion(s1, s2)) # 輸出: True
?
三、總結與交流
通過深入學習串的高級操作,包括求子串、串的替換、字符串反轉和去重,我們進一步拓展了對串的處理能力。同時,通過在LeetCode上解決一系列與串相關的題目,我們不僅鞏固了理論知識,還提升了解決實際問題的能力。
聽聽大家在學習串的高級操作和解決LeetCode題目過程中的體驗和見解。有沒有在解決某個題目時發現獨特的解題思路?或者在實際項目中應用這些操作時遇到了什么挑戰?歡迎在評論區分享你的故事,讓我們一起交流學習,共同進步!