【程序人生】leetcode(二)

說在前面

這篇博客中部分題目答案來自leetcode評論區,不是本人原創。感謝原作者的工作。這裏記錄在這篇博客中,方便日後回顧、學習

羅馬數字轉整數(原創)

羅馬數字包含以下七種字符: I, V, X, L,C,D 和 M。

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

例如, 羅馬數字2寫做II,即爲兩個並列的1。12寫做XII,即爲X+II。 27寫做XXVII, 即爲XX+V+II。

通常情況下,羅馬數字中小的數字在大的數字的右邊。但也存在特例,例如4不寫做IIII,而是IV。數字1在數字5的左邊,所表示的數等於大數5減小數1得到的數值4。同樣地,數字9表示爲IX。這個特殊的規則只適用於以下六種情況:

  • I可以放在V(5)和X (10)的左邊,來表示4和9。
  • X可以放在L(50)和C(100)的左邊,來表示40和90。
  • C可以放在D(500)和M(1000)的左邊,來表示400和900。

給定一個羅馬數字,將其轉換成整數。輸入確保在 1 到 3999 的範圍內。

class Solution:
    def romanToInt(self, s: str) -> int:
        hash_map = {"I":1, "V":5, "X":10, "L":50, "C":100, "D":500, "M":1000}
        value = 0
        s = list(s[::-1])
        for i, each in enumerate(s):
            if i == 0:
                value = value + hash_map[each]
            else:
                if hash_map[each] >= hash_map[s[i-1]]:
                    value = value + hash_map[each]
                else:
                    value = value - hash_map[each]

        return value

整數轉羅馬數字(轉載)

羅馬數字包含以下七種字符: I, V, X, L,C,D 和 M。

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

例如, 羅馬數字2寫做II,即爲兩個並列的1。12寫做XII,即爲X+II。 27寫做XXVII, 即爲XX+V+II。

通常情況下,羅馬數字中小的數字在大的數字的右邊。但也存在特例,例如4不寫做IIII,而是IV。數字1在數字5的左邊,所表示的數等於大數5減小數1得到的數值4。同樣地,數字9表示爲IX。這個特殊的規則只適用於以下六種情況:

  • I可以放在V(5)和X (10)的左邊,來表示4和9。
  • X可以放在L(50)和C(100)的左邊,來表示40和90。
  • C可以放在D(500)和M(1000)的左邊,來表示400和900。

給定一個整數,將其轉爲羅馬數字。輸入確保在1到3999的範圍內。

class Solution:
    def intToRoman(self, num: int) -> str:
        hash_map = {"M":1000, "CM":900, "D":500, "CD":400, "C":100, "XC":90, 
                    "L":50, "XL":40, "X":10, "IX":9, "V":5, "IV":4, "I":1}
        
        string = ""
        while num>0:
            for key in hash_map:
                while num>=hash_map[key]:
                    num-=hash_map[key]
                    string +=key

        return string

盛水最多的容器(轉載)

給你n個非負整數a1a_1a2a_2,…,ana_n,每個數代表座標中的一個點(i,ai)(i, a_i)。在座標內畫n條垂直線,垂直線i的兩個端點分別爲(i,ai)(i, a_i)(i,0)(i, 0)。找出其中的兩條線,使得它們與x軸共同構成的容器可以容納最多的水。

說明:你不能傾斜容器,且n的值至少爲 2。
在這裏插入圖片描述
圖中垂直線代表輸入數組[1,8,6,2,5,4,8,3,7]。在此情況下,容器能夠容納水(表示爲藍色部分)的最大值爲49。

class Solution:
    def maxArea(self, height: List[int]) -> int:
        left = 0
        right = len(height) - 1
        maxArea = 0
        while left < right:
            b = right - left
            if height[left] < height[right]:
                h = height[left]
                left += 1
            else:
                h = height[right]
                right -= 1
            area = b*h
            if maxArea < area:
                maxArea = area
        return maxArea

三數之和(轉載)

給你一個包含n個整數的數組nums,判斷nums中是否存在三個元素a,b,c,使得a + b + c = 0?請你找出所有滿足條件且不重複的三元組。

注意:答案中不可以包含重複的三元組。

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        # 升序排列
        nums.sort()
        res =[]
    
        for i in range(len(nums)):
            if i == 0 or nums[i]>nums[i-1]:
                l = i+1
                r = len(nums)-1
                while l < r:
                    s = nums[i] + nums[l] +nums[r]
                    if s == 0:
                        res.append([nums[i],nums[l],nums[r]])
                        l += 1
                        r -= 1
                        while l < r and nums[l] == nums[l-1]:
                            l += 1
                        while r > l and nums[r] == nums[r+1]:
                            r -= 1
                    elif s > 0:
                        r -= 1
                    else :
                        l += 1
        return res
  1. 將數組排序
  2. 定義三個指針,i、j、k。遍歷i,那麼這個問題就可以轉化爲在i之後的數組中尋找nums[j]+nums[k]=nums[i]nums[j]+nums[k]=-nums[i]這個問題,也就將三數之和問題轉變爲二數之和

合併兩個有序鏈表(原創)

將兩個升序鏈表合併爲一個新的升序鏈表並返回。新鏈表是通過拼接給定的兩個鏈表的所有節點組成的。

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

class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        if l1 is None:
            return l2
        if l2 is None:
            return l1

        # 遍歷a, 插入start
        if l1.val >= l2.val:
            a = l1
            start = l2
        else:
            a = l2
            start = l1

        node = start
        while a is not None:
            try:
                while not (node.val <= a.val <= node.next.val):
                    node = node.next
            
                linshi = ListNode(a.val)
                linshi.next = node.next
                node.next = linshi

            except AttributeError:
                node.next = a
                return start
                
            a = a.next

        return start

電話號碼的字母組合(原創)

給定一個僅包含數字2-9的字符串,返回所有它能表示的字母組合。

給出數字到字母的映射如下(與電話按鍵相同)。注意1不對應任何字母。
在這裏插入圖片描述

class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        hash_map = {2:["a", "b", "c"], 3:["d", "e", "f"], 
                    4:["g", "h", "i"], 5:["j", "k", "l"],
                    6:["m", "n", "o"], 7:["p", "q", "r", "s"],
                    8:["t", "u", "v"], 9:["w", "x", "y", "z"]}
        
        num = len(digits)
        result = []

        while num > 0:
            key = int(digits[0:1])
            digits = digits[1:]
            num = len(digits)

            if result == []:
                for each in hash_map[key]:
                    result.append(each)
            else:
                res = []
                for i in result:
                    for j in hash_map[key]:
                        res.append(i+j)
                result = res
                
        return result

兩兩交換鏈表中的節點(轉載)

給定一個鏈表,兩兩交換其中相鄰的節點,並返回交換後的鏈表。

你不能只是單純的改變節點內部的值,而是需要實際的進行節點交換。

示例:

給定 1->2->3->4, 你應該返回 2->1->4->3.

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

class Solution:
    def swapPairs(self, head: ListNode) -> ListNode:
        if (head is None) or (head.next is None):
            return head
        
        linshi = ListNode(head.next.val)
        linshi.next = head
        head.next = self.swapPairs(head.next.next)

        return linshi

使用遞歸來解決該題,主要就是遞歸的三部曲

  • 找終止條件:本題終止條件很明顯,當遞歸到鏈表爲空或者鏈表只剩一個元素的時候,沒得交換了,自然就終止了。
  • 找返回值:返回給上一層遞歸的值應該是已經交換完成後的子鏈表。
  • 單次的過程因爲遞歸是重複做一樣的事情,所以從宏觀上考慮,只用考慮某一步是怎麼完成的。我們假設待交換的倆節點分別爲head和next,next的應該接受上一級返回的子鏈表(參考第2步)。就相當於是一個含三個節點的鏈表交換前兩個節點,就很簡單了,想不明白的畫畫圖就ok。

括號生成(轉載)

數字n代表生成括號的對數,請你設計一個函數,用於能夠生成所有可能的並且有效的括號組合。

示例:

輸入:n = 3
輸出:[
“((()))”,
“(()())”,
“(())()”,
“()(())”,
“()()()”
]

class Solution:
    def generateParenthesis(self, n: int) -> List[str]:
        result = []
        def dfs(num_left, num_right, string):
            if num_left == 0 and num_right == 0:
                result.append(string)
                return
            
            if num_left > 0:
                dfs(num_left - 1, num_right, string + "(")
            if num_right > num_left:
                dfs(num_left, num_right - 1, string + ")")
        dfs(n, n, "")

        return result

有效的括號(轉載)

給定一個只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判斷字符串是否有效。

有效字符串需滿足:

  • 左括號必須用相同類型的右括號閉合。
  • 左括號必須以正確的順序閉合。

注意空字符串可被認爲是有效字符串。

class Solution:
    def isValid(self, s: str) -> bool:
        while (("[]" in s) or ("()" in s) or ("{}" in s)):
            s = s.replace("[]", "")
            s = s.replace("()", "")
            s = s.replace("{}", "")
        
        if s == "":
            return True
        else:
            return False

最接近的三數之和(原創)

給定一個包括n個整數的數組nums和一個目標值target。找出nums中的三個整數,使得它們的和與target最接近。返回這三個數的和。假定每組輸入只存在唯一答案。

示例:

例如,給定數組 nums = [-1,2,1,-4], 和 target = 1.
與 target 最接近的三個數的和爲 2. (-1 + 2 + 1 = 2).

class Solution:
    def threeSumClosest(self, nums: List[int], target: int) -> int:
        # 判斷是不是最接近target
        res = 1000000000000000000
        # 返回結果
        result = 0

        # 升序排列
        nums.sort()
        
        for i, each in enumerate(nums[:-2]):
            linshi = nums[i+1:]
            # 左指針
            p1 = 0 
            # 右指針
            p2 = len(linshi) - 1
            
            if abs(each + linshi[p1] + linshi[p2] - target) == 0:
                return each + linshi[p1] + linshi[p2]
            
            if abs(each + linshi[p1] + linshi[p2] - target) < res:
                result = each + linshi[p1] + linshi[p2]
                res = abs(each + linshi[p1] + linshi[p2] - target)

            while p1 < p2:
                if (each + linshi[p1] + linshi[p2] - target) == 0:
                    return each + linshi[p1] + linshi[p2]
                
                if abs(each + linshi[p1] + linshi[p2] - target) < res:
                    result = each + linshi[p1] + linshi[p2]
                    res = abs(each + linshi[p1] + linshi[p2] - target)

                if (each + linshi[p1] + linshi[p2] - target) > 0:
                    p2 = p2 -1
                else:
                    p1 = p1 + 1
        
        return result

結語

如果您有修改意見或問題,歡迎留言或者通過郵箱和我聯繫。
手打很辛苦,如果我的文章對您有幫助,轉載請註明出處。

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