Leetcode 007:整數反轉---Python

一、寫在前面

之前寫過的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
如果判斷表達式1True ,則變量1 = 結果A 否則 變量1 = 結果B
a = 1 if 3 > 4 else 0
結果 : 0


top4解法:Python裏的三目表達式(a if A else b 其中A是個判斷表達式),列表推導式,遍歷循環~

其實看過這些top級解法後,我發現,核心思想和我是一樣的,只是在實現某個邏輯功能是方法不同,所以這是我要學習的地方,當然Leetcode上還有很多其他解法,歡迎大家去看看,思考出屬於自己的代碼。

六、結語

沒力氣了,健身去了,堅持就完了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章