python反轉(zhuǎn)字符串的七種解法總結(jié)
題目難度
簡單
題目描述
編寫一個(gè)函數(shù),其作用是將輸入的字符串反轉(zhuǎn)過來。輸入字符串以字符數(shù)組s的形式給出。
不要給另外的數(shù)組分配額外的空間,你必須原地修改輸入數(shù)組、使用O(1)的額外空間解決這一問題。
示例
示例 1
輸入:s = ["h","e","l","l","o"]輸出:["o","l","l","e","h"]
示例 2
輸入:s = ["H","a","n","n","a","h"]輸出:["h","a","n","n","a","H"]
提示信息
1 <= s.length <= 105s[i]都是 ASCII 碼表中的可打印字符。
解法一:雙指針
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
# 定義左右指針
left, right = 0, len(s) - 1
while left < right:
s[left], s[right] = s[right], s[left]
left += 1
right -= 1
- 雙指針概念:使用兩個(gè)指針分別指向字符串的起始位置和結(jié)束位置,通過交換指針?biāo)傅脑貋韺?shí)現(xiàn)字符串的反轉(zhuǎn)。這種方法在處理需要對數(shù)組或字符串進(jìn)行兩端操作的問題時(shí)非常常見。
- Python 的同時(shí)賦值特性:
s[left], s[right] = s[right], s[left]這種寫法可以同時(shí)對兩個(gè)變量進(jìn)行賦值,無需借助中間變量。Python 會(huì)先計(jì)算等號(hào)右邊的值,然后同時(shí)將值賦給等號(hào)左邊的變量。在這個(gè)過程中,實(shí)際上是先創(chuàng)建了一個(gè)包含s[right]和s[left]的元組,然后將這個(gè)元組的值分別賦給s[left]和s[right]。
解法二:棧結(jié)構(gòu)
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
原地修改,不用返回s,直接對s操作反轉(zhuǎn)了!
"""
stack = [] # 定義空棧stack[]
for char in s: # 從頭遍歷s中所有字符
stack.append(char) # 入棧用.append(xxx)實(shí)現(xiàn)
# 實(shí)現(xiàn)了將s所有字符入棧,利用棧的結(jié)構(gòu)特點(diǎn)
# 先入棧的后出棧,就實(shí)現(xiàn)了反轉(zhuǎn)
# for i in len(s): len(s)是個(gè)數(shù)字,長度!for要for一個(gè)范圍
for i in range(len(s)):
s[i] = stack.pop() # i指定s[i]位置進(jìn)行修改,.pop是出棧操作
- 棧的概念和操作:棧是一種數(shù)據(jù)結(jié)構(gòu),遵循后進(jìn)先出(LIFO)的原則。在這個(gè)解法中,首先將字符串中的字符依次壓入棧中,然后再從棧中彈出字符并覆蓋原字符串的對應(yīng)位置,實(shí)現(xiàn)反轉(zhuǎn)。使用列表來模擬棧的操作,
.append()方法用于將元素壓入棧(列表末尾),.pop()方法用于彈出棧頂元素(列表末尾的元素)。 - 棧的結(jié)構(gòu)特點(diǎn):后進(jìn)先出、先進(jìn)后出正好適合做反轉(zhuǎn)操作!
解法三:range函數(shù)
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
n = len(s)
for i in range(n // 2):
s[i], s[n - i - 1] = s[n - i - 1], s[i]
- range函數(shù)的使用:range函數(shù)可以生成一個(gè)整數(shù)序列,例如range(n // 2)生成一個(gè)從0到字符串長度一半的整數(shù)序列,用于遍歷字符串的前半部分。則i與n-1-i是對應(yīng)的要交換的位置。
- 字符串長度的獲取與索引操作:
解法四:reversed函數(shù)
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
s[:] = reversed(s)
對這段代碼中涉及的reversed函數(shù)和切片操作的詳細(xì)解釋:
一、reversed函數(shù)
作用:
reversed是 Python 的內(nèi)置函數(shù),它接收一個(gè)可迭代對象作為參數(shù),并返回一個(gè)反轉(zhuǎn)后的迭代器。這個(gè)迭代器可以遍歷輸入可迭代對象的元素,但順序是反轉(zhuǎn)后的。- 例如,對于列表
[1, 2, 3],reversed([1, 2, 3])會(huì)返回一個(gè)迭代器,當(dāng)遍歷這個(gè)迭代器時(shí),會(huì)依次得到3、2、1。
特點(diǎn):
reversed函數(shù)不會(huì)直接修改原始的可迭代對象,而是返回一個(gè)新的迭代器。如果要獲取反轉(zhuǎn)后的具體內(nèi)容,可以將其轉(zhuǎn)換為列表、元組等具體的數(shù)據(jù)結(jié)構(gòu)。- 例如,
list(reversed([1, 2, 3]))會(huì)得到[3, 2, 1]。
二、切片操作
基本概念:
- 在 Python 中,切片是一種用于從序列(如列表、字符串、元組等)中提取一部分元素的操作。它通過指定起始索引、結(jié)束索引和步長來定義要提取的部分。
- 切片的語法是
sequence[start:stop:step],其中start是起始索引(默認(rèn)為 0),stop是結(jié)束索引(不包括該索引處的元素),step是步長(默認(rèn)為 1)。 - 例如,對于列表
my_list = [0, 1, 2, 3, 4, 5],my_list[1:4]會(huì)得到[1, 2, 3]。
在代碼中的作用:
s[:]是一種特殊的切片操作,表示對整個(gè)序列s進(jìn)行切片。這里的作用是將reversed(s)返回的反轉(zhuǎn)后的迭代器轉(zhuǎn)換為列表(或其他可迭代對象,具體取決于s的類型),并將其賦值給s,從而實(shí)現(xiàn)原地修改s。- 相當(dāng)于用反轉(zhuǎn)后的內(nèi)容替換了原始序列中的所有元素,達(dá)到了反轉(zhuǎn)字符串(或列表等)的目的。
為什么代碼這樣寫
- 首先,
reversed(s)返回一個(gè)反轉(zhuǎn)后的迭代器,這個(gè)迭代器包含了s中元素的反轉(zhuǎn)順序。 - 然后,通過
s[:] = reversed(s),將這個(gè)反轉(zhuǎn)后的迭代器轉(zhuǎn)換為具體的數(shù)據(jù)結(jié)構(gòu)(通常是列表),并將其賦值給s的整個(gè)切片。這樣做的好處是可以原地修改s,而不需要?jiǎng)?chuàng)建一個(gè)新的列表來存儲(chǔ)反轉(zhuǎn)后的結(jié)果,從而節(jié)省了內(nèi)存空間。 - 同時(shí),這種寫法簡潔明了,利用了 Python 的內(nèi)置函數(shù)和切片操作的強(qiáng)大功能,以一種高效的方式實(shí)現(xiàn)了字符串(或列表等)的反轉(zhuǎn)。
解法五:切片
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
s[:] = s[::-1]
讓我們來通俗地理解這段代碼涉及的知識(shí)點(diǎn)。
一、字符串切片
想象字符串就像一串漂亮的珠子,每個(gè)珠子代表一個(gè)字符。字符串切片就像是從這串珠子中選取一部分珠子的工具。
正常的切片,比如
s[start:end:step]:start是你開始選取珠子的位置。end是你停止選取珠子的位置(但不包括這個(gè)位置上的珠子)。step是你每次選取珠子的間隔。- 例如
s[2:5],就像是從這串珠子的第三個(gè)位置開始,一直拿到第五個(gè)位置之前的珠子。
特殊的切片
s[::-1]:- 這里沒有指定開始和結(jié)束位置,意味著從字符串的開頭一直取到結(jié)尾。
- 步長為
-1,就像是你從字符串的末尾開始,每次向前走一步,依次選取珠子,一直走到字符串的開頭。所以這樣就得到了一個(gè)反轉(zhuǎn)后的字符串。
二、賦值給s[:]
現(xiàn)在想象s是一個(gè)裝著珠子的盒子。s[:]表示整個(gè)盒子里的所有珠子。把s[::-1]賦值給s[:],就像是把用特殊切片方法得到的反轉(zhuǎn)后的那串珠子,全部替換掉原來盒子里的珠子。這樣就實(shí)現(xiàn)了在不創(chuàng)建新盒子(不占用額外空間)的情況下,把原來盒子里的珠子順序反轉(zhuǎn)了。
所以這段代碼的作用就是通過巧妙地利用字符串切片和賦值操作,原地反轉(zhuǎn)了給定的字符串(實(shí)際上是字符列表)。
- 知識(shí)要點(diǎn):
- 字符串切片的高級(jí)用法:切片操作
s[::-1]表示從字符串末尾開始,每次向前移動(dòng)一步,直到字符串開頭,從而得到反轉(zhuǎn)后的字符串。這種切片語法非常強(qiáng)大,可以用于快速提取字符串的一部分、跳過特定元素等。在這里,通過將切片結(jié)果賦值給s[:],實(shí)現(xiàn)了原地反轉(zhuǎn)字符串。
- 字符串切片的高級(jí)用法:切片操作
解法六:列表推導(dǎo)
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
s[:] = [s[i] for i in range(len(s) - 1, -1, -1)]
- 知識(shí)要點(diǎn):
- 列表推導(dǎo)式的原理:列表推導(dǎo)式是一種簡潔的語法,用于快速生成列表。在這個(gè)解法中,
[s[i] for i in range(len(s) - 1, -1, -1)]生成一個(gè)從字符串末尾到開頭的字符列表。通過遍歷從字符串長度減 1 到 0 的索引,將每個(gè)字符添加到列表中。然后通過切片賦值將這個(gè)列表覆蓋原字符串,實(shí)現(xiàn)反轉(zhuǎn)。 - 索引的反向遍歷:
range(len(s) - 1, -1, -1)表示從字符串長度減 1 開始,每次遞減 1,直到 -1(不包括 -1),實(shí)現(xiàn)了對字符串索引的反向遍歷。
- 列表推導(dǎo)式的原理:列表推導(dǎo)式是一種簡潔的語法,用于快速生成列表。在這個(gè)解法中,
以下是對這種解法思路的詳細(xì)解釋,包括涉及的語法知識(shí):
一、列表推導(dǎo)式的原理
基本概念:
- 列表推導(dǎo)式是一種簡潔的語法,用于快速生成新的列表。它的基本形式是
[expression for item in iterable if condition],其中expression是對每個(gè)item進(jìn)行的操作,iterable是一個(gè)可迭代對象,if condition是可選的過濾條件。 - 例如,
[i * 2 for i in range(5)]會(huì)生成一個(gè)包含0, 2, 4, 6, 8的列表。這里對range(5)生成的每個(gè)整數(shù)進(jìn)行了乘以 2 的操作。
- 列表推導(dǎo)式是一種簡潔的語法,用于快速生成新的列表。它的基本形式是
在本題中的應(yīng)用:
[s[i] for i in range(len(s) - 1, -1, -1)]這個(gè)列表推導(dǎo)式的目的是生成一個(gè)反轉(zhuǎn)后的字符列表。s[i]表示取原始字符串s中索引為i的字符。range(len(s) - 1, -1, -1)是一個(gè)整數(shù)序列,從字符串的最后一個(gè)索引開始,依次遞減到第一個(gè)索引(不包括 -1)。這樣就實(shí)現(xiàn)了對字符串索引的反向遍歷。
二、索引的反向遍歷
range函數(shù)的參數(shù)解釋:range(len(s) - 1, -1, -1)中,len(s) - 1是起始值,表示字符串的最后一個(gè)索引。-1是結(jié)束值,表示要遍歷到索引為 0 的前一個(gè)位置,因?yàn)樗饕菑?0 開始的,所以不包括 -1 這個(gè)位置。- 最后一個(gè)
-1是步長,表示每次遞減 1。
反向遍歷的作用:
- 通過這種反向遍歷,可以依次取到字符串中的每個(gè)字符,從最后一個(gè)字符開始,到第一個(gè)字符結(jié)束。這樣就可以構(gòu)建一個(gè)反轉(zhuǎn)后的字符列表。
三、切片賦值實(shí)現(xiàn)反轉(zhuǎn)
s[:]的作用:s[:]表示對整個(gè)字符串(實(shí)際上是字符列表)進(jìn)行切片操作。這里的作用是將新生成的反轉(zhuǎn)后的字符列表覆蓋到原始字符串上,實(shí)現(xiàn)原地反轉(zhuǎn)。- 相當(dāng)于把原來的字符串用新生成的反轉(zhuǎn)后的字符列表替換掉。
這種解法的設(shè)計(jì)思路是利用列表推導(dǎo)式快速生成反轉(zhuǎn)后的字符列表,然后通過切片賦值將其覆蓋到原始字符串上,從而實(shí)現(xiàn)不使用額外空間的字符串反轉(zhuǎn)。這種方法展示了 Python 語言中列表推導(dǎo)式和切片操作的靈活性和強(qiáng)大功能。
解法七:reverse()函數(shù)
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
s_list = list(s)
s_list.reverse()
s[:] = s_list
- 知識(shí)要點(diǎn):
- 列表的 reverse 方法:列表有一個(gè)
reverse方法,可以原地反轉(zhuǎn)列表。在這個(gè)解法中,首先將輸入字符串轉(zhuǎn)換為列表s_list,然后調(diào)用s_list.reverse()原地反轉(zhuǎn)列表。最后,將反轉(zhuǎn)后的列表轉(zhuǎn)換回字符串,并通過切片賦值覆蓋原字符串,實(shí)現(xiàn)反轉(zhuǎn)。 - 類型轉(zhuǎn)換:
list(s)將字符串轉(zhuǎn)換為列表,這樣就可以使用列表的方法進(jìn)行操作。然后,將反轉(zhuǎn)后的列表轉(zhuǎn)換回字符串時(shí),通過切片賦值s[:] = s_list實(shí)現(xiàn)原地修改字符串。
- 列表的 reverse 方法:列表有一個(gè)
綜上所述,這些解法展示了 Python 中多種不同的編程技巧和數(shù)據(jù)結(jié)構(gòu)的用法,通過巧妙地利用這些知識(shí),可以高效地解決字符串反轉(zhuǎn)問題。
補(bǔ)充:
元組:在Python中,元組(Tuple)是一種不可變的有序序列,它與列表類似,但有一些重要的區(qū)別。以下是關(guān)于元組的詳細(xì)介紹:
元組的定義
- 元組使用小括號(hào)
()來表示,其中的元素用逗號(hào)分隔。例如:my_tuple = (1, 2, 3)定義了一個(gè)包含三個(gè)整數(shù)元素的元組。 - 元組也可以不使用小括號(hào),直接用逗號(hào)分隔元素來定義,例如:
my_tuple = 1, 2, 3與上面的定義是等價(jià)的。
元組的特點(diǎn)
- 不可變性:元組一旦創(chuàng)建,其元素就不能被修改、刪除或替換。這意味著元組提供了一種數(shù)據(jù)完整性的保證,適合用于存儲(chǔ)不應(yīng)該被改變的數(shù)據(jù)集合。
- 有序性:元組中的元素是有序的,可以通過索引來訪問。與列表一樣,元組的索引從0開始,例如
my_tuple[0]將訪問元組中的第一個(gè)元素。
在同時(shí)賦值中的作用
- 在
s[left], s[right] = s[right], s[left]這種同時(shí)賦值的語句中,等號(hào)右邊的s[right], s[left]實(shí)際上構(gòu)成了一個(gè)臨時(shí)的元組。Python會(huì)先計(jì)算這個(gè)元組的值,即獲取s[right]和s[left]的值,并將它們組合成一個(gè)元組(s[right]的值, s[left]的值)。 - 然后,Python會(huì)將這個(gè)元組中的元素按照順序分別賦給等號(hào)左邊的變量
s[left]和s[right]。這種方式簡潔地實(shí)現(xiàn)了兩個(gè)變量值的交換,而無需使用中間變量來臨時(shí)存儲(chǔ)值。
為什么使用元組概念
- 簡潔性:使用元組可以在一行代碼中完成多個(gè)變量的賦值操作,使代碼更加簡潔和易讀。相比于使用中間變量來實(shí)現(xiàn)交換,這種方式更加直觀和高效。
- 原子性:元組的不可變性保證了在賦值過程中的原子性。即整個(gè)賦值操作是一個(gè)不可分割的整體,要么全部成功,要么全部失敗。不會(huì)出現(xiàn)中間狀態(tài),從而避免了一些潛在的錯(cuò)誤和不一致性。
- 與Python語法的一致性:Python的語法設(shè)計(jì)中廣泛使用了元組和類似元組的結(jié)構(gòu)。例如,函數(shù)可以返回多個(gè)值,實(shí)際上返回的就是一個(gè)元組。在很多其他的場景中,元組也被用于表示一組相關(guān)的值。因此,在同時(shí)賦值中使用元組概念與Python的整體語法風(fēng)格和編程習(xí)慣是一致的。
元組在Python中有多種應(yīng)用場景,以下是一些常見的例子:
數(shù)據(jù)打包與解包
- 多值返回:函數(shù)可以返回多個(gè)值,這些值會(huì)被自動(dòng)打包成一個(gè)元組。例如:
def get_name_and_age():
return "Alice", 25
name, age = get_name_and_age()
print(name)
print(age)
在這個(gè)例子中,get_name_and_age函數(shù)返回了一個(gè)包含姓名和年齡的元組,然后通過多變量賦值將元組中的值分別賦給了name和age變量。
- 數(shù)據(jù)交換:如前面提到的交換變量的值,使用元組可以在不借助中間變量的情況下簡潔地實(shí)現(xiàn)交換操作。
a = 5 b = 10 a, b = b, a print(a) print(b)
函數(shù)參數(shù)傳遞
- 固定參數(shù)順序:當(dāng)函數(shù)需要接收多個(gè)參數(shù),且這些參數(shù)的順序和含義是固定的時(shí),可以使用元組來傳遞參數(shù)。例如,對于一個(gè)繪制圖形的函數(shù),可能需要接收坐標(biāo)點(diǎn)的元組作為參數(shù)。
def draw_point(point):
x, y = point
print(f"繪制點(diǎn) ({x}, {y})")
point = (3, 4)
draw_point(point)
- 可變參數(shù):在函數(shù)定義中,可以使用元組來接收不確定數(shù)量的參數(shù)。通過在參數(shù)前加上
*,可以將多個(gè)參數(shù)收集到一個(gè)元組中。
def print_args(*args):
for arg in args:
print(arg)
print_args(1, 2, 3, "hello")
數(shù)據(jù)保護(hù)與不可變性
- 防止數(shù)據(jù)意外修改:當(dāng)需要確保數(shù)據(jù)不被修改時(shí),元組是一個(gè)很好的選擇。例如,配置信息、常量數(shù)據(jù)等可以使用元組來存儲(chǔ),以防止在程序的其他部分意外地修改這些數(shù)據(jù)。
COLORS = ('red', 'green', 'blue')
# 以下代碼會(huì)引發(fā)錯(cuò)誤,因?yàn)樵M是不可變的
# COLORS[0] = 'yellow'
數(shù)據(jù)結(jié)構(gòu)中的元素
- 字典的鍵:元組可以作為字典的鍵,因?yàn)樗遣豢勺兊?。這在需要使用多個(gè)值作為字典鍵的情況下非常有用。
student_info = {('Alice', 25): '優(yōu)秀', ('Bob', 22): '良好'}
print(student_info[('Alice', 25)])
- 集合的元素:元組也可以作為集合的元素,同樣是因?yàn)槠洳豢勺冃浴<现械脑乇仨毷俏ㄒ坏?,使用元組作為元素可以方便地存儲(chǔ)和操作多個(gè)相關(guān)的值。
my_set = {(1, 2), (3, 4), (1, 2)}
print(my_set)
并行迭代
- 可以同時(shí)迭代多個(gè)可迭代對象,將它們的元素組合成元組進(jìn)行處理。例如,同時(shí)遍歷兩個(gè)列表并打印對應(yīng)的元素。
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
for name, age in zip(names, ages):
print(f"{name} is {age} years old.")
數(shù)據(jù)庫操作
- 在與數(shù)據(jù)庫交互時(shí),查詢結(jié)果通常以元組的形式返回。每個(gè)元組代表一行數(shù)據(jù),其中的元素對應(yīng)于查詢結(jié)果中的列。
import sqlite3
conn = sqlite3.connect('example.db')
cursor = conn.cursor()
cursor.execute("SELECT name, age FROM students")
results = cursor.fetchall()
for row in results:
print(row)
conn.close()
這些只是元組在Python中的一些常見應(yīng)用場景,實(shí)際上,元組在各種不同的編程任務(wù)和數(shù)據(jù)處理場景中都有廣泛的應(yīng)用,它的不可變性和簡潔性使其成為Python編程中一個(gè)非常有用的數(shù)據(jù)結(jié)構(gòu)。
以下是對range函數(shù)的詳細(xì)介紹:
一、range函數(shù)的特點(diǎn)
生成整數(shù)序列:
range函數(shù)主要用于生成一個(gè)整數(shù)序列。它可以接受一個(gè)、兩個(gè)或三個(gè)參數(shù),分別對應(yīng)不同的用法。- 當(dāng)只傳入一個(gè)參數(shù)
n時(shí),range(n)會(huì)生成從0到n - 1的整數(shù)序列。例如,range(5)會(huì)生成0, 1, 2, 3, 4。 - 當(dāng)傳入兩個(gè)參數(shù)
start和end時(shí),range(start, end)會(huì)生成從start到end - 1的整數(shù)序列。例如,range(2, 5)會(huì)生成2, 3, 4。 - 當(dāng)傳入三個(gè)參數(shù)
start、end和step時(shí),range(start, end, step)會(huì)生成從start開始,每次增加step,直到小于end的整數(shù)序列。例如,range(1, 10, 2)會(huì)生成1, 3, 5, 7, 9。
高效性:
range對象是一種“惰性求值”的序列類型,它不會(huì)一次性生成所有的整數(shù),而是在需要的時(shí)候逐個(gè)生成。這使得它在處理大量整數(shù)序列時(shí)非常高效,尤其是在內(nèi)存受限的情況下。
可迭代性:
range對象是可迭代的,可以在for循環(huán)中直接使用。例如:for i in range(5): print(i)會(huì)依次打印0, 1, 2, 3, 4。
二、range函數(shù)的使用方式
基本用法:
- 如前面提到的,用于生成整數(shù)序列,并在
for循環(huán)中進(jìn)行遍歷。 - 例如:
for i in range(3): print(f"第 {i + 1} 次循環(huán)")。
- 如前面提到的,用于生成整數(shù)序列,并在
結(jié)合列表推導(dǎo)式:
- 可以與列表推導(dǎo)式結(jié)合使用,快速生成列表。例如:
new_list = [i * 2 for i in range(5)]會(huì)生成一個(gè)包含0, 2, 4, 6, 8的列表。
- 可以與列表推導(dǎo)式結(jié)合使用,快速生成列表。例如:
作為函數(shù)參數(shù):
- 一些函數(shù)接受可迭代對象作為參數(shù),
range生成的整數(shù)序列可以作為這些函數(shù)的參數(shù)。例如,sum(range(1, 11))可以計(jì)算從 1 到 10 的整數(shù)之和。
- 一些函數(shù)接受可迭代對象作為參數(shù),
三、range函數(shù)的應(yīng)用場景
循環(huán)控制:
- 在需要進(jìn)行固定次數(shù)循環(huán)的情況下,
range非常有用。例如,遍歷一個(gè)列表并對每個(gè)元素進(jìn)行處理。 - 例如:
my_list = [1, 2, 3, 4, 5],for i in range(len(my_list)):可以遍歷列表的索引,從而訪問和修改列表中的元素。
- 在需要進(jìn)行固定次數(shù)循環(huán)的情況下,
生成索引序列:
- 在需要對序列進(jìn)行索引操作時(shí),可以使用
range生成索引序列。例如,在字符串反轉(zhuǎn)的例子中,通過range(n // 2)生成字符串前半部分的索引序列,用于交換字符。
- 在需要對序列進(jìn)行索引操作時(shí),可以使用
步長控制:
- 當(dāng)需要按照特定的步長進(jìn)行遍歷或生成序列時(shí),可以使用第三個(gè)參數(shù)指定步長。例如,生成奇數(shù)序列可以使用
range(1, 10, 2)。
- 當(dāng)需要按照特定的步長進(jìn)行遍歷或生成序列時(shí),可以使用第三個(gè)參數(shù)指定步長。例如,生成奇數(shù)序列可以使用
與其他數(shù)據(jù)結(jié)構(gòu)結(jié)合:
- 可以與列表、元組、集合等數(shù)據(jù)結(jié)構(gòu)結(jié)合使用,進(jìn)行各種操作。例如,生成一個(gè)包含特定范圍內(nèi)整數(shù)的列表,或者對一個(gè)可迭代對象進(jìn)行切片操作時(shí),可以使用
range來確定切片的起始和結(jié)束位置。
- 可以與列表、元組、集合等數(shù)據(jù)結(jié)構(gòu)結(jié)合使用,進(jìn)行各種操作。例如,生成一個(gè)包含特定范圍內(nèi)整數(shù)的列表,或者對一個(gè)可迭代對象進(jìn)行切片操作時(shí),可以使用
總之,range函數(shù)是 Python 中非常實(shí)用的一個(gè)工具,它在循環(huán)控制、索引操作、生成序列等方面有廣泛的應(yīng)用,可以提高代碼的效率和可讀性。
時(shí)空復(fù)雜度分析
以下是對這七種解法的時(shí)間復(fù)雜度和空間復(fù)雜度分析以及對比:
一、解法一:雙指針
時(shí)間復(fù)雜度:
- 由于只需要一次遍歷字符串的一半長度,所以時(shí)間復(fù)雜度為 O ( n ) O(n)O(n),其中
n是字符串的長度。
- 由于只需要一次遍歷字符串的一半長度,所以時(shí)間復(fù)雜度為 O ( n ) O(n)O(n),其中
空間復(fù)雜度:
- 只使用了兩個(gè)指針變量,沒有額外的數(shù)據(jù)結(jié)構(gòu),所以空間復(fù)雜度為 O ( 1 ) O(1)O(1)。
二、解法二:棧結(jié)構(gòu)
時(shí)間復(fù)雜度:
- 遍歷一次字符串將字符入棧,再遍歷一次字符串出棧并賦值,總共遍歷兩次字符串,時(shí)間復(fù)雜度為 O ( n ) O(n)O(n)。
空間復(fù)雜度:
- 使用了一個(gè)棧來存儲(chǔ)字符串中的字符,最壞情況下需要存儲(chǔ)整個(gè)字符串,所以空間復(fù)雜度為 O ( n ) O(n)O(n)。
三、解法三:range 函數(shù)
時(shí)間復(fù)雜度:
- 同樣是遍歷字符串的一半長度進(jìn)行交換操作,時(shí)間復(fù)雜度為 O ( n ) O(n)O(n)。
空間復(fù)雜度:
- 沒有使用額外的數(shù)據(jù)結(jié)構(gòu),只使用了幾個(gè)變量,空間復(fù)雜度為 O ( 1 ) O(1)O(1)。
四、解法四:reversed 函數(shù)和切片
時(shí)間復(fù)雜度:
- 創(chuàng)建反轉(zhuǎn)迭代器和進(jìn)行切片賦值的操作時(shí)間復(fù)雜度為 O ( n ) O(n)O(n)。
空間復(fù)雜度:
reversed函數(shù)返回的迭代器不占用額外空間,切片賦值是原地操作,空間復(fù)雜度為 O ( 1 ) O(1)O(1)。
五、解法五:切片
時(shí)間復(fù)雜度:
- 切片操作本身的時(shí)間復(fù)雜度可以認(rèn)為是 O ( n ) O(n)O(n),因?yàn)樗婕暗奖闅v字符串。
空間復(fù)雜度:
- 切片操作是原地修改,沒有額外的數(shù)據(jù)結(jié)構(gòu),空間復(fù)雜度為 O ( 1 ) O(1)O(1)。
六、解法六:列表推導(dǎo)
時(shí)間復(fù)雜度:
- 列表推導(dǎo)式遍歷字符串的時(shí)間復(fù)雜度為 O ( n ) O(n)O(n),再加上切片賦值的時(shí)間復(fù)雜度為 O ( n ) O(n)O(n),總體時(shí)間復(fù)雜度為 O ( n ) O(n)O(n)。
空間復(fù)雜度:
- 列表推導(dǎo)式創(chuàng)建了一個(gè)新的臨時(shí)列表,最壞情況下長度為
n,但最后通過切片賦值覆蓋原列表,所以空間復(fù)雜度為 O ( n ) O(n)O(n)(臨時(shí)列表占用空間)和 O ( 1 ) O(1)O(1)(最終的空間復(fù)雜度)的混合,考慮到最終原地修改,整體可以認(rèn)為是 O ( 1 ) O(1)O(1)。
- 列表推導(dǎo)式創(chuàng)建了一個(gè)新的臨時(shí)列表,最壞情況下長度為
七、解法七:reverse()函數(shù)
時(shí)間復(fù)雜度:
- 列表的
reverse方法時(shí)間復(fù)雜度為 O ( n ) O(n)O(n)。
- 列表的
空間復(fù)雜度:
- 創(chuàng)建了一個(gè)新的列表,然后再進(jìn)行切片賦值,臨時(shí)列表占用空間為 O ( n ) O(n)O(n),但最終原地修改,整體空間復(fù)雜度可以認(rèn)為是 O ( 1 ) O(1)O(1)。
對比分析:
時(shí)間復(fù)雜度:七種解法的時(shí)間復(fù)雜度都是 O ( n ) O(n)O(n),差別不大。但是在實(shí)際運(yùn)行中,由于操作的不同,可能會(huì)有一些細(xì)微的性能差異。例如,雙指針、range 函數(shù)、reversed 函數(shù)和切片等方法相對較為簡潔直接,可能在某些情況下執(zhí)行速度稍快。
空間復(fù)雜度:解法一、三、四、五、七的空間復(fù)雜度都是 O ( 1 ) O(1)O(1),因?yàn)樗鼈兌际窃匦薷?,沒有使用額外的線性空間。解法二使用了棧,最壞情況下空間復(fù)雜度為 O ( n ) O(n)O(n)。解法六在列表推導(dǎo)過程中創(chuàng)建了臨時(shí)列表,雖然最終也是原地修改,但在過程中可能占用額外空間,整體也可以認(rèn)為是 O ( 1 ) O(1)O(1)。
綜上所述,在解決這個(gè)問題時(shí),如果對空間要求較高,可以優(yōu)先選擇雙指針、range 函數(shù)、reversed 函數(shù)和切片等空間復(fù)雜度為 O ( 1 ) O(1)O(1) 的方法。如果更注重代碼的簡潔性和可讀性,可以根據(jù)具體情況選擇合適的解法。
總結(jié)
到此這篇關(guān)于python反轉(zhuǎn)字符串的七種解法的文章就介紹到這了,更多相關(guān)python反轉(zhuǎn)字符串內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
pyspark給dataframe增加新的一列的實(shí)現(xiàn)示例
這篇文章主要介紹了pyspark給dataframe增加新的一列的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
如何使用Python連接?SSH?服務(wù)器并執(zhí)行命令
實(shí)際開發(fā)中,有時(shí)候經(jīng)常需要查看日志,有時(shí)候使用ssh工具打開就為了看一下錯(cuò)誤日志又比較麻煩,所以今天帶來一個(gè)簡單的基于python的小工具,感興趣的朋友跟隨小編一起看看吧2023-11-11
教你如何在Pycharm中導(dǎo)入requests模塊
這篇文章主要介紹了教你如何在Pycharm中導(dǎo)入requests模塊,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09
靈活運(yùn)用Python 枚舉類來實(shí)現(xiàn)設(shè)計(jì)狀態(tài)碼信息
在python中枚舉是一種類(Enum,IntEnum),存放在enum模塊中。枚舉類型可以給一組標(biāo)簽賦予一組特定的值,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09
對Tensorflow中權(quán)值和feature map的可視化詳解
今天小編就為大家分享一篇對Tensorflow中權(quán)值和feature map的可視化詳解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-06-06
深入理解Python 關(guān)于supper 的 用法和原理
這篇文章主要介紹了Python 關(guān)于supper 的 用法和原理分析,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧2018-02-02
Python多線程爬蟲實(shí)戰(zhàn)_爬取糗事百科段子的實(shí)例
下面小編就為大家分享一篇Python多線程爬蟲實(shí)戰(zhàn)_爬取糗事百科段子的實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2017-12-12
Python生成指定數(shù)量的優(yōu)惠碼實(shí)操內(nèi)容
在本篇文章里小編給大家整理了關(guān)于Python生成指定數(shù)量的優(yōu)惠碼的實(shí)例內(nèi)容以及相關(guān)代碼,有需要的朋友們學(xué)習(xí)下。2019-06-06

