iT邦幫忙

2022 iThome 鐵人賽

DAY 7
0
自我挑戰組

leetcode 30天 不中斷解題挑戰系列 第 7

Day7 leetcode 隨機挑題 (鏈結串列、Simulation)

  • 分享至 

  • xImage
  •  

首先是 21. Merge Two Sorted Lists (easy)
https://leetcode.com/problems/merge-two-sorted-lists

簡單來說就是要把兩個linked list合併為一個,並且要按照val大小,算是linked list的基本題型吧
想法:

  1. 首先先建置兩個空的linked list (ans,temp),一個要當作答案,一個要能夠跑到最後。
  2. 一開始先讓temp.next變成list1 or list2(看誰第一個值比較大)(為什麼不直接temp = list原因是因為邏輯比較好寫,若最後temp.next直接變成None的話,後面很難接剩下的東西)
  3. 接下來,就是利用迴圈持續裝東西,直到list1或list2空掉為止
  4. 最後,若list1或list2還有東西直接接到temp.next的地方
  5. return ans (因為temp會一直往後面的節點跑,不會儲存全部的linked list)
    最後答案呈現為這樣:
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
        #鏈結串列的基本題型
        ans = temp = ListNode()#ans紀錄答案,temp紀錄跑到哪了
        while list1 and list2:#當都不為空時
            if list1.val < list2.val:#比大小
                temp.next = list1
                temp = temp.next#值裝完後,要控制下個節點
                list1 = list1.next#值被裝了,所以跑到下個節點
                # list1, temp = list1.next, list1
            else:
                temp.next = list2
                temp = temp.next
                list2 = list2.next
                # list2, temp = list2.next, list2
        if list1:
            temp.next = list1
        if list2:
            temp.next = list2
        return ans.next
            

再來是 206. Reverse Linked List (easy)
https://leetcode.com/problems/reverse-linked-list

把一個linked list倒轉過來標準題目。
首先是最好理解的方法:
想法:
1.把值都拿取出來填到一串列裡
2.將串列進行翻轉,按照此串列順序建立新的linked list

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        r = []
        if head is None:
            return
        while head:
            r.append(head.val)
            head = head.next
        result= temp = ListNode(r[-1])
        for i in r[-2::-1]:
            temp.next = ListNode(i)
            temp = temp.next
        return result

但想一下也知道這樣處理方式其實不是很快,只能說標準,因此改成以下方法
1.先用temp儲存原本head的next值
2.把head.next會從倒轉後的倒數一個node開始儲存
3.ans儲存翻轉後的結果
4.head變成temp,執行下一輪

class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        ans = None
        #[1,2,3,4,5]
        while head:
            temp = head.next#1. [2,3,4,5] #2. [3,4,5] 
            head.next = ans#1.獲取None #2.[1,None]
            ans = head #1. [1,None] #2.[2,[1,None]]
            head = temp #1. [2,3,4,5] #2.[3,4,5]
        return ans

但老實說不知道為啥,跑起來速度還比較慢,可以的話我想求救QAQ


再來是 876. Middle of the Linked List
https://leetcode.com/problems/middle-of-the-linked-list

把linked list切半,並只輸出後半部
沒什麼好講的,就是在一個回合裡面,一個人跑一步一個人跑兩步的問題。
所以我就用這概念直接寫了這方法

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def middleNode(self, head: Optional[ListNode]) -> Optional[ListNode]:
        if head is None:
            return 0
        vL = 0
        temp = head
        while head:
            head = head.next
            if vL:
                temp = temp.next
                vL = 0
            else:
                vL = 1
        return temp

最後temp裡的就是答案。
不過後來有是著長是另外一種方法:紀錄mid的位置再跑一次

class Solution:
    
    def middleNode(self, head: Optional[ListNode]) -> Optional[ListNode]:
        if head is None:
            return 0
        vL = 0
        temp = head
        while head:
            head = head.next
            vL+=1
        mid = vL//2
        while mid:
            temp = temp.next
            mid -= 1
        return temp

感覺上差不多


接下來是 985. Sum of Even Numbers After Queries (medium)
https://leetcode.com/problems/sum-of-even-numbers-after-queries/

首先會給一個整數串列nums,以及一個指令串列queries,queries裡面的每筆資料都是串列而內含兩個數字n1,n2,第二個數字代表要去對nums的第n2個數字進行加上n1的運算。每進行運算一次,都要計算nums裡的偶數和,並放置到答案的串列。

首先是暴力解:
1.迭代queries
2.直接對n2進行加上n1的運算
3.計算nums的偶數和
4.丟到ans裡

class Solution:
    #白癡法,果然TLE
    def sumEvenAfterQueries(self, nums: List[int], qL: List[List[int]]) -> List[int]:
        result = []
        def calEvenSum(numList):
            result = 0
            for i in numList:
                if i%2 == 0:
                    result +=i
            return result
        for i in qL:
            nums[i[1]] += i[0]
            result.append(calEvenSum(nums))
        return result

完全不意外的TLE。

真正的方式應該是這樣:

  1. 先計算nums的偶數和total
  2. 由於每次只會變動一個數字,所以只需要由此判斷每次total需不需要更動
  3. 判斷兩次,一次在變動前,一次變動後。
  4. 如果變動前就是偶數,則需先從total裡扣掉;如果變動後是偶數,需要加至total當中。
  5. 反覆計算,結束
class Solution:
    #由於一次只變一個數字
    #改那個數字所造成的結果即可
    def sumEvenAfterQueries(self, nums: List[int], qL: List[List[int]]) -> List[int]:
        total = sum(i for i in nums if i%2==0)
        result = []
        for i in qL:
            temp = 0
            if not nums[i[1]]%2:#1.檢測改變前是否為even
                temp = nums[i[1]]
            nums[i[1]] += i[0]
            total -= temp
            if not nums[i[1]]%2:#2.檢測改變後是否為even
                total += nums[i[1]]
            result.append(total)
        return result

以上就是今天的練習感謝觀看OUO


上一篇
Day6 leetcode 隨機挑題 (前綴和、字串處理)
下一篇
Day8 leetcode 隨機挑題(String, Greedy, Linked List)
系列文
leetcode 30天 不中斷解題挑戰30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言