1. 程式人生 > 其它 >20天組隊學習 | 騰訊精選2.4.5題

20天組隊學習 | 騰訊精選2.4.5題

技術標籤:leetcodepython

目錄

002 兩數相加

題目描述

給出兩個 **非空** 的連結串列用來表示兩個非負的整數。
其中,它們各自的位數是按照 **逆序** 的方式儲存的,並且它們的每個節點只能儲存 **一位** 數字。
如果,我們將這兩個數相加起來,則會返回一個新的連結串列來表示它們的和。
您可以假設除了數字 0 之外,這兩個數都不會以 0 開頭。
示例 1:
輸入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
輸出:7 -> 0 -> 8
原因:342 + 465 = 807

解題方法
在這裡插入圖片描述
python程式碼

class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None


class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        result = ListNode(0)
        l3 = result
        val = 0   # val是進位  cur是兩數相加得到的個位數
        # 兩條連結串列長度可能不相等,因此結束迴圈後,需要判斷是否有未遍歷完的連結串列,有則單獨遍歷,沒有則進入下一步。
while val or l1 or l2: # 只要val,l1,l2有一個不為0或none均可執行 # val=兩數相加的和/10的除數 cur=兩數相加的和/10的餘數 比如7+8=15/10=1...5所以val=1,cur=5 val, cur = divmod(val + (l1.val if l1 else 0) + (l2.val if l2 else 0), 10) l3.next = ListNode(cur) l3 = l3.next l1 = l1.
next if l1 else None l2 = l2.next if l2 else None return result.next def generateList(l: list) -> ListNode: prenode = ListNode(0) lastnode = prenode for val in l[::-1]: # 逆序 lastnode.next = ListNode(val) lastnode = lastnode.next return prenode.next def printList(l: ListNode): while l: print("{}".format(l.val), end=' ') l = l.next print('') if __name__ == "__main__": l1 = generateList([1, 5, 8]) l2 = generateList([9, 1, 2, 8]) printList(l1) printList(l2) s = Solution() sum = s.addTwoNumbers(l1, l2) printList(sum)

004 尋找兩個正序陣列的中位數

題目描述

給定兩個大小為 m 和 n 的有序陣列 nums1 和 nums2。
請你找出這兩個有序陣列的中位數,並且要求演算法的時間複雜度為 O(log(m + n))。
你可以假設 nums1 和 nums2 不會同時為空。
示例 1:
nums1 = [1, 3]
nums2 = [2]
則中位數是 2.0

解題方法

1.暴力求解
2.合併兩個有序陣列

當兩個有序陣列的中位數之和為奇數時,中位數只有一個,將它返回。
當兩個有序陣列的中位數之和為偶數時,中位數只有兩個,返回合併、排序以後位於中間的兩個數的平均數

3.二分查詢

此方法最主要的是找到兩個有序陣列的分割線,如下圖所示。
其中的標準是:
假設陣列1的個數為m,陣列2的個數為n
1.紅線左邊的元素個數=(m+n+1)/2(向下取整)
2.紅線左邊所有的各元素數值要小於等於紅線右邊所有的各元素數值(注意是元素數值不是之和)

偶數的情況
奇數的情況

分割線確定好後,就可以直接找到中位數:
1.當m+n為奇數時:返回分割線左邊元素的最大值
2.當m+n為偶數時:返回分割線左邊元素的最大值與右邊元素的最小值的平均數

python程式碼

暴力求解:

class Solution:
    def findMedianSortedArrays(self, nums1, nums2):
        m = len(nums1)
        n = len(nums2)
        nums1.extend(nums2)  # 合併
        nums1.sort()  # 排序
        print(m + n)
        if (m + n) & 1:  # 奇數 
            return nums1[(m + n - 1) >> 1]  #左移1位相當於乘以2, 右移1位相當於除以2
        else:            # 偶數
            return (nums1[(m + n - 1) >> 1] + nums1[(m + n) >> 1]) / 2

if __name__ == "__main__":
    s = Solution()
    A = [1, 5, 7, 8, 1, 2, 3]
    B = [2]
    print(s.findMedianSortedArrays(A, B))

二分法求解:

import sys
class Solution(object):
    def findMedianSortedArrays(self, nums1, nums2):
        ls1, ls2 = len(nums1), len(nums2)
        if ls1 < ls2:
            return self.findMedianSortedArrays(nums2, nums1)
        l, r = 0, ls2 * 2
        while l <= r:
            mid2 = (l + r) >> 1
            mid1 = ls1 + ls2 - mid2
            L1 = -sys.maxsize - 1 if mid1 == 0 else nums1[(mid1 - 1) >> 1]
            L2 = -sys.maxsize - 1 if mid2 == 0 else nums2[(mid2 - 1) >> 1]
            R1 = sys.maxsize if mid1 == 2 * ls1 else nums1[mid1 >> 1]
            R2 = sys.maxsize if mid2 == 2 * ls2 else nums2[mid2 >> 1]
            if L1 > R2:
                l = mid2 + 1
            elif L2 > R1:
                r = mid2 - 1
            else:
                return (max(L1, L2) + min(R1, R2)) / 2.0


if __name__ == '__main__':
    # begin
    s = Solution()
    print(s.findMedianSortedArrays([1, 2, 3, 4], [5, 6, 7, 8, 9]))

005 最長迴文子串

題目描述

給定一個字串 s,找到 s 中最長的迴文子串。你可以假設 s 的最大長度為 1000。
示例 1:
輸入: "babad"
輸出: "bab"
注意: "aba" 也是一個有效答案。

解題方法
1.暴力求解
在這裡插入圖片描述

2.中心擴散法

中心位置有以下兩種可能:
在這裡插入圖片描述
在這裡插入圖片描述

3.動態規劃

python程式碼

中心拓展法:

class Solution:
    def longestPalindrome(self, s: str) -> str:
        size = len(s)
        if size < 2:
            return s

        # 至少是 1
        max_len = 1
        res = s[0]

        for i in range(size):
            palindrome_odd, odd_len = self.__center_spread(s, size, i, i)
            palindrome_even, even_len = self.__center_spread(s, size, i, i + 1)

            # 當前找到的最長迴文子串
            cur_max_sub = palindrome_odd if odd_len >= even_len else palindrome_even
            if len(cur_max_sub) > max_len:
                max_len = len(cur_max_sub)
                res = cur_max_sub

        return res

    def __center_spread(self, s, size, left, right):
        """
        left = right 的時候,此時迴文中心是一個字元,迴文串的長度是奇數
        right = left + 1 的時候,此時迴文中心是一個空隙,迴文串的長度是偶數
        """
        i = left
        j = right

        while i >= 0 and j < size and s[i] == s[j]:
            i -= 1
            j += 1
        return s[i + 1:j], j - i - 1


if __name__ == '__main__':
    # begin
    s = Solution()
    print(s.longestPalindrome("qbcaacb"))