Leetcode題解 - Easy - 1

先做Easy級別的題目吧~(由于剛開始刷還沒規(guī)劃好递鹉,這篇里面先夾雜了兩道中等難度的題)

1-兩數(shù)之和

要求

給定一個整數(shù)數(shù)組 nums 和一個目標(biāo)值 target啼止,請你在該數(shù)組中找出和為目標(biāo)值的 兩個 整數(shù)门岔。

你可以假設(shè)每種輸入只會對應(yīng)一個答案羞延。但是横辆,你不能重復(fù)利用這個數(shù)組中同樣的元素各墨。

示例:

給定 nums = [2, 7, 11, 15], target = 9

因為 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

分析

最笨辦法是O(n^2),可以借助哈希表(字典)進(jìn)行優(yōu)化瘩绒。遍歷一遍元素猴抹,并將元素的值作為key下標(biāo)作為value插入哈希表中。注意锁荔,遍歷的同時蟀给,對于當(dāng)前元素,拿目標(biāo)值減去當(dāng)前值阳堕,然后去哈希表里找是否存在跋理,如果存在則說明找到了一對兒,直接返回即可恬总。

代碼

class Solution:
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        mem = {}
        for index, val in enumerate(nums):
            if (target - val) in mem.keys():
                return [mem[target-val], index]
            mem[val] = index
        return []

2-兩數(shù)相加 (中等難度)

題目

給出兩個 非空 的鏈表用來表示兩個非負(fù)的整數(shù)薪介。其中,它們各自的位數(shù)是按照 逆序 的方式存儲的越驻,并且它們的每個節(jié)點只能存儲 一位 數(shù)字汁政。

如果,我們將這兩個數(shù)相加起來缀旁,則會返回一個新的鏈表來表示它們的和记劈。

您可以假設(shè)除了數(shù)字 0 之外,這兩個數(shù)都不會以 0 開頭并巍。

示例:

輸入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
輸出:7 -> 0 -> 8
原因:342 + 465 = 807

思路

兩個鏈表一起讀取目木,相加進(jìn)位。這個題難點在于有很多特殊情況懊渡,不容易考慮周全刽射。

比如以下特殊用例

[5]  # 需要考慮進(jìn)位
[5]

[9,8] # 需要考慮長度不均等
[1]

[1]  # 需要考慮長度不均等和進(jìn)位
[9,9]

代碼

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        head = ListNode(0)
        head.next = l1
        carry = 0

        while l1 and l2:  # 兩個列表長度相同的部分
            s = l1.val + l2.val + carry
            val, carry = s % 10, s // 10
            l1.val = val
            prev, l1, l2 = l1, l1.next, l2.next
        
        l = l1 or l2  # 處理l1或l2余下的部分
        prev.next = l
        while l and carry:
            s = l.val + carry
            val, carry = s%10, s//10
            l.val = val
            prev, l = l, l.next
        
        if carry:  # 最后千萬記得要處理進(jìn)位
            prev.next = ListNode(1)
        
        return head.next
                

3-無重復(fù)字符的最長子串 (中等難度)

問題

給定一個字符串军拟,請你找出其中不含有重復(fù)字符的 最長子串 的長度。

示例 1:

輸入: "abcabcbb"
輸出: 3
解釋: 因為無重復(fù)字符的最長子串是 "abc"誓禁,所以其長度為 3懈息。
示例 2:

輸入: "bbbbb"
輸出: 1
解釋: 因為無重復(fù)字符的最長子串是 "b",所以其長度為 1摹恰。
示例 3:

輸入: "pwwkew"
輸出: 3
解釋: 因為無重復(fù)字符的最長子串是 "wke"辫继,所以其長度為 3。

請注意俗慈,你的答案必須是 子串 的長度姑宽,"pwke" 是一個子序列,不是子串闺阱。

思路

滑動窗口來解決炮车,左右兩個索引ij,用哈希表記錄當(dāng)前窗口中的元素酣溃。當(dāng)讀到j(luò)時如果不重復(fù)示血,則j繼續(xù)讀,如果重復(fù)救拉,則記下窗口的長度,然后從哈希表中讀取重復(fù)元素所在的位置瘫拣,并將i移動到它的下一個位置亿絮,繼續(xù)滑動窗口,最后得到最長的長度麸拄。

代碼

class Solution:
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        ans = 0
        mem = {}
        i = 0
        for j in range(0, len(s)):
            if s[j] in mem.keys():
                i = max(mem[s[j]], i)
            ans = max(ans, j - i + 1)
            mem[s[j]] = j + 1
        return ans
            

上面是參照官方解答寫的python代碼派昧,非常簡潔。而且本來我認(rèn)為當(dāng)遇到重復(fù)值之后拢切,挪動i之后應(yīng)該清空mem蒂萎,mem只記住當(dāng)前窗口中出現(xiàn)的元素,但這個代碼里面并沒有清空mem淮椰,而是接著用了mem五慈,玄機在于 i = max(mem[s[j]], i)這句,這句實現(xiàn)了:如果當(dāng)前元素出現(xiàn)在mem中主穗,并不意味著在當(dāng)前窗口中一定遇到重復(fù)值泻拦,而是判斷一下,如果重復(fù)元素的位置小于i則不是當(dāng)前窗口中出現(xiàn)了重復(fù)值忽媒,不更新i争拐,如果大于i則是出現(xiàn)了重復(fù)值,更新i晦雨。

寥寥幾句就把很多情況和判斷都給涵蓋了架曹,真是簡潔啊隘冲。

7-整數(shù)反轉(zhuǎn)

問題

給出一個 32 位的有符號整數(shù),你需要將這個整數(shù)中每位上的數(shù)字進(jìn)行反轉(zhuǎn)绑雄。

示例 1:

輸入: 123
輸出: 321
示例 2:

輸入: -123
輸出: -321
示例 3:

輸入: 120
輸出: 21
注意:

假設(shè)我們的環(huán)境只能存儲得下 32 位的有符號整數(shù)展辞,則其數(shù)值范圍為 [?231, 231 ? 1]。請根據(jù)這個假設(shè)绳慎,如果反轉(zhuǎn)后整數(shù)溢出那么就返回 0纵竖。

思路

可以借助棧,123 % 10 = 3杏愤, 12 % 10 = 2靡砌, 1 % 10 = 1, 然后彈棧珊楼, 1 x 1 = 1通殃, 1 + 2 x 10 = 21, 21 + 3 x 100 = 321厕宗,完成計算画舌。

其實也可以在不借助棧的情況下完成,先彈出 123 % 10 = 3已慢, 123 // 10 = 12曲聂,將3存放到另一個數(shù)字變量ans中。然后 12 % 10 = 2, 12 // 10 = 1佑惠,對于ans朋腋,有 3 * 10 + 2 = 32。繼續(xù)膜楷,1 % 10 = 1, 1 // 10 = 0旭咽,對于ans有 32 * 10 + 1 = 321。不借助外部存儲完成了反轉(zhuǎn)赌厅。

代碼

class Solution:
    def reverse(self, x):
        """
        :type x: int
        :rtype: int
        """
        minus = 1
        if x < 0:
            minus = -1
            x *= minus
        ans = 0
        while x != 0:
            pop = x % 10
            x = x // 10
            ans = ans * 10 + pop
        ans *= minus
        # 由于leetcode要求溢出時返回0穷绵,而python寫的時候該溢出的用例未溢出,所以判斷一下溢出
        if - 2 ** 31 < ans < 2 ** 31 - 1:
            return ans
        else:
            return 0

9- 回文數(shù)

問題

判斷一個整數(shù)是否是回文數(shù)特愿≈倌回文數(shù)是指正序(從左向右)和倒序(從右向左)讀都是一樣的整數(shù)。

例如揍障, 121 是回文數(shù)宗收, -121 不是回文數(shù), 10 不是回文數(shù)亚兄。

思路

轉(zhuǎn)為字符串混稽,兩端讀取判斷是否回文。

不轉(zhuǎn)為字符串的話,就通過除10和取余將數(shù)字反轉(zhuǎn)匈勋,然后判斷反轉(zhuǎn)前后的兩個整數(shù)是否相等礼旅。

優(yōu)化:例如,1221洽洁,是否可以加快速度呢痘系?其實只要將后一半數(shù)字反轉(zhuǎn),與剩下的前一半數(shù)字比較饿自,即可判斷是否回文汰翠。(這個只反轉(zhuǎn)一半的代碼略)

代碼

轉(zhuǎn)換為字符串的解法:

class Solution:
    def isPalindrome(self, x):
        """
        :type x: int
        :rtype: bool
        """
        if x < 0:
            return False
        data = str(x)
        i, j = 0, len(data) - 1
        while i < j:
            if data[i] != data[j]:
                return False
            i += 1
            j -= 1
        return True

巧妙利用 python 語法:

class Solution:
    def isPalindrome(self, x):
        """
        :type x: int
        :rtype: bool
        """
        if x >= 0 and str(x) == str(x)[::-1]:
            a = True
        else :
            a = False
        return a

反轉(zhuǎn)整個數(shù)字的解法:

class Solution:
    def isPalindrome(self, x):
        """
        :type x: int
        :rtype: bool
        """
        if x < 0:
            return False
        remainder = x % 10
        devision = x // 10
        reverse = remainder
        while devision != 0:
            remainder = devision % 10
            devision = devision // 10
            reverse = reverse * 10 + remainder
        return x == reverse

13-羅馬數(shù)字轉(zhuǎn)整數(shù)

問題

羅馬數(shù)字包含以下七種字符: I, V昭雌, X复唤, L,C烛卧,D 和 M佛纫。

字符          數(shù)值
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

例如, 羅馬數(shù)字 2 寫做 II 总放,即為兩個并列的 1呈宇。12 寫做 XII ,即為 X + II 局雄。 27 寫做 XXVII, 即為 XX + V + II 甥啄。

通常情況下,羅馬數(shù)字中小的數(shù)字在大的數(shù)字的右邊炬搭。但也存在特例蜈漓,例如 4 不寫做 IIII,而是 IV尚蝌。數(shù)字 1 在數(shù)字 5 的左邊,所表示的數(shù)等于大數(shù) 5 減小數(shù) 1 得到的數(shù)值 4 充尉。同樣地飘言,數(shù)字 9 表示為 IX。這個特殊的規(guī)則只適用于以下六種情況:

I 可以放在 V (5) 和 X (10) 的左邊驼侠,來表示 4 和 9姿鸿。
X 可以放在 L (50) 和 C (100) 的左邊,來表示 40 和 90倒源。 
C 可以放在 D (500) 和 M (1000) 的左邊苛预,來表示 400 和 900。

給定一個羅馬數(shù)字笋熬,將其轉(zhuǎn)換成整數(shù)热某。輸入確保在 1 到 3999 的范圍內(nèi)。

示例 1:

輸入: "III"
輸出: 3

示例 2:

輸入: "IV"
輸出: 4

示例 3:

輸入: "IX"
輸出: 9

示例 4:

輸入: "LVIII"
輸出: 58
解釋: L = 50, V= 5, III = 3.

示例 5:

輸入: "MCMXCIV"
輸出: 1994
解釋: M = 1000, CM = 900, XC = 90, IV = 4.

思路

最主要是想清楚思路,不要陷入很多if else里面昔馋。
建立一個字符和值的對應(yīng)筹吐,從左往右讀取,如果當(dāng)前字符代表的數(shù)字比下一個字符的大秘遏,則在總結(jié)果里加上丘薛,如果小,則減去邦危。

上面思路雖然看起簡單洋侨,在本題的前提下——輸入的羅馬數(shù)字一定是正確的——是沒有問題的。

代碼

class Solution:
    def romanToInt(self, s):
        """
        :type s: str
        :rtype: int
        """
        num = {
            'I': 1,
            'V': 5,
            'X': 10,
            'L': 50,
            'C': 100,
            'D': 500,
            'M': 1000,
        }
        score = 0
        for i in range(0, len(s)):
            if i < len(s) - 1 and num[s[i+1]] > num[s[i]]:
                score -= num[s[i]]
            else:
                score += num[s[i]]
        return score
        

14- 最長公共前綴

問題

編寫一個函數(shù)來查找字符串?dāng)?shù)組中的最長公共前綴倦蚪。

如果不存在公共前綴希坚,返回空字符串 ""。

示例 1:

輸入: ["flower","flow","flight"]
輸出: "fl"

示例 2:

輸入: ["dog","racecar","car"]
輸出: ""
解釋: 輸入不存在公共前綴审丘。

說明:
所有輸入只包含小寫字母 a-z 吏够。

思路

  • 縱向掃描:從下標(biāo)0開始,判斷每一個字符串的下標(biāo)0滩报,判斷是否全部相同锅知。直到遇到不全部相同的下標(biāo)。時間性能為O(n*m)脓钾。

  • 橫向掃描:前兩個字符串找公共子串碗降,將其結(jié)果和第三個字符串找公共子串……直到最后一個串。時間性能為O(n*m)捞慌。

  • 借助trie字典樹甘凭。將這些字符串存儲到trie樹中。那么trie樹的第一個分叉口之前的單分支樹的就是所求握截。(這個思路也挺好的飞崖,而且用到了高級一點的方法)

代碼

# 縱向掃描
class Solution:
    def longestCommonPrefix(self, strs):
        """
        :type strs: List[str]
        :rtype: str
        """
        if not strs:
            return ''
        if len(strs) == 1:
            return strs[0]
        cursor = -1
        ok = True
        while ok:
            cursor += 1
            if cursor == len(strs[0]): # 首個串已走完
                cursor -= 1
                break
            current_char = strs[0][cursor]
            for st in strs[1:]:
                if cursor == len(st) or st[cursor] != current_char: # 串走完或不匹配
                    cursor -= 1
                    ok = False
                    break
        return strs[0][:cursor+1]
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市谨胞,隨后出現(xiàn)的幾起案子固歪,更是在濱河造成了極大的恐慌,老刑警劉巖胯努,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件牢裳,死亡現(xiàn)場離奇詭異,居然都是意外死亡叶沛,警方通過查閱死者的電腦和手機蒲讯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來灰署,“玉大人判帮,你說我怎么就攤上這事局嘁。” “怎么了脊另?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵导狡,是天一觀的道長。 經(jīng)常有香客問我偎痛,道長旱捧,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任踩麦,我火速辦了婚禮枚赡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘谓谦。我一直安慰自己贫橙,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布反粥。 她就那樣靜靜地躺著卢肃,像睡著了一般。 火紅的嫁衣襯著肌膚如雪才顿。 梳的紋絲不亂的頭發(fā)上莫湘,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天,我揣著相機與錄音郑气,去河邊找鬼幅垮。 笑死,一個胖子當(dāng)著我的面吹牛尾组,可吹牛的內(nèi)容都是我干的忙芒。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼讳侨,長吁一口氣:“原來是場噩夢啊……” “哼呵萨!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起跨跨,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤潮峦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后歹叮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體跑杭,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡铆帽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年咆耿,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片爹橱。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡萨螺,死狀恐怖窄做,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情慰技,我是刑警寧澤椭盏,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站吻商,受9級特大地震影響掏颊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜艾帐,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一乌叶、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧柒爸,春花似錦准浴、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至今野,卻和暖如春葡公,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背腥泥。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工匾南, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蛔外。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓蛆楞,卻偏偏與公主長得像,于是被迫代替她去往敵國和親夹厌。 傳聞我的和親對象是個殘疾皇子豹爹,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容