一、寫在前面
之前寫過的Leetcode筆記:點擊查看
今天給大家分享的是LeetCode 007:整數反轉,爲面試而生,期待你的加入。
二、今日題目
給出一個 32 位的有符號整數,你需要將這個整數中每位上的數字進行反轉。
說明:
假設我們的環境只能存儲得下 32 位的有符號整數,則其數值範圍爲 [−231, 231 − 1]。請根據這個假設,如果反轉後整數溢出那麼就返回 0。
示例:
輸入: 123
輸出: 321
輸入: -123
輸出: -321
輸入: 120
輸出: 21
三、 分析
這個題目看着不怎麼難,因爲業務邏輯很簡單:把一個整數逆置,題目給了數據範圍,給了特殊案例,基本思路如下:拿到輸入的數據,判斷是否爲負數,想辦法把數據從個位開始與高位互換位置,判斷互換位置後的數據是否溢出。
四、解題
- 方法一:
int
轉變爲str
,然後遍歷字符串(Python裏int是不可迭代的,所以得轉換一下),將原先的高位變成低位。
# -*- coding: utf-8 -*-
"""
@author = 老表
@date = 2019-08-29
@個人公衆號 : 簡說Python
"""
class Solution:
def reverse(self, x: int) -> int:
y = 0 # 返回結果
j = 0 # 冪指數(位權重)
flag = 0 # 正負標誌位
if x < 0: # 處理負數情況
flag = 1
x = x * (-1)
for i in str(x): # 轉變成字符串進行遍歷
# 進行組裝,以前的高位變成低位
y = y + int(i)*pow(10, j)
j = j + 1
if y > pow(2, 31)-1: # 處理溢出情況
return 0
if flag == 1: # 處理負數情況
y = -1 * y
return y
執行結果:
修改一下對負數和冪指數的處理方法,效果會好一點點,但本質上都是O(n)時間複雜度(n爲x的位數):
# -*- coding: utf-8 -*-
"""
@author = 老表
@date = 2019-08-29
@個人公衆號 : 簡說Python
"""
class Solution:
def reverse(self, x: int) -> int:
y = 0
j = 0
flag = 0
for i in str(x):
if i == "-":
flag = 1
continue
y = y + int(i)*10**j
j = j + 1
if y > 2147483647:
return 0
if flag == 1:
y = -y
return y
- 方法二:
# -*- coding: utf-8 -*-
"""
@author = 老表
@date = 2019-08-26
@個人公衆號 : 簡說Python
"""
class Solution:
def reverse(self, x: int) -> int:
y = 0 # 返回結果
flag = 0 # 正負標誌位
if x < 0: # 如果爲負,先化爲正數
x = -x
flag =1
while x != 0: # 循環拆解
pop = x % 10 # 取出低位
x = x // 10 # 取出剩餘
y = y * 10 + pop # 連接重組數據,低位變高位
if y > 2147483647: # 判斷是否溢出
return 0
if flag == 1: # 處理負數情況
return -y
return y
- 提交結果
效果依然不理想,對代碼稍加改動:
class Solution:
def reverse(self, x: int) -> int:
y = 0 # 結果
while x != 0: # 遍歷拆分
pop = x % 10 # 取出低位
x = x // 10 # 取出剩餘數
if x < 0 and pop != 0: # 如果爲負數另做處理
pop = pop - 10
x = x + 1
y = y * 10 + pop # 重新組裝,低位變成高位
if y < -2147483648: # 判斷溢出
return 0
if y > 2147483647: # 判斷溢出
return 0
return y
好一點點?!看不怎麼出來,確實,從時間複雜度來說還是差不多的,後面的改動需要注意的是對負數的處理:
# 在Python裏負數的除法和正數是相反的,取餘數會向10靠近,取商會向-∞靠近
例如:
-12 % 10
結果:8
-123 // 10
結果:-13
然而對於本題來說,
-12➗10取餘,我們想得到的是-2,
-123➗10取商,我們想得到的是-12
很簡單
pop = pop - 10 # 取餘後減10
x = x + 1 # 取商後加1
五、疑惑
我今天發現,在Leetcode 上可以看top級的解題方法了,雖然只有代碼,也很有參考學習價值。
方法:
提交自己的答案後,會有一個運行時間分佈圖,點擊上面的黃色柱狀條即可查看對應運行時間實現的代碼了。
top1的解法
:感覺?看起來?確實高級,先轉爲str,然後用了內置的字符串函數startswith(判斷正負),然後用到了切片,嗯~原來這樣速度比較快~
top2解法
:和top1差不多,不同點在於,轉換爲字符串後,用內置的字符串處理函數rstrip處理了數據,(刪除右邊的“-”),然後是正負判斷。
top3解法
:用到的挺多的,正則,abs(取絕對值函數),join(列表鏈接成字符串函數),reverse(字符串逆置函數),Python裏的三目表達式(a if A else b 其中A是個判斷表達式),數據轉換(int,str)。
# Python裏的三目表達式
# 很棒的一種判斷語句書寫方法,讓代碼看起來比較簡潔,給大家舉個例子
語言描述:
形式 : 變量1 = 結果A if 判斷表達式1 else 結果B
如果判斷表達式1爲True ,則變量1 = 結果A 否則 變量1 = 結果B
a = 1 if 3 > 4 else 0
結果 : 0
top4解法
:Python裏的三目表達式(a if A else b 其中A是個判斷表達式),列表推導式,遍歷循環~
其實看過這些top級解法後,我發現,核心思想和我是一樣的,只是在實現某個邏輯功能是方法不同,所以這是我要學習的地方,當然Leetcode上還有很多其他解法,歡迎大家去看看,思考出屬於自己的代碼。
六、結語
沒力氣了,健身去了,堅持就完了。