劍指offer(python)--鏈表

01-從尾到頭打印鏈表

輸入一個鏈表,按鏈表值從尾到頭的順序返回一個ArrayList。

問題:1 ,如何輸入一個鏈表?—字典
2. 如何獲得鏈表值 --字典映射 ?指針 數值
3. 如何從頭到尾順序返回?---- for i in range ()返回 總體來說就是將字典轉化爲列表 (簡單說就是把這個鏈表上的節點一個個讀到列表中,然後用[::-1]切片的方法實現逆序)
b = a[i:j] 表示複製a[i]到a[j-1],以生成新的list對象

補充
> a = [0,1,2,3,4,5,6,7,8,9]
b = a[i:j] # [1,2]
當i缺省時,默認爲0,即 a[:3]相當於a[0:3] ;
當j缺省時,默認爲len(alist), 即a[1:]相當於a[1:10]
當i,j都存在時,表示複製i到j的數據
當i,j都缺省時,a[:]就相當於完整複製一份a

b = a[i:j:s]表示:i,j與上面的一樣,但s表示步進,
缺省爲1. 所以a[i:j:1]相當於a[i:j]
當s<0時,i缺省時,默認爲-1.
j缺省時,默認爲-len(a)-1 所以a[::-1]相當於 a[-1:-len(a)-1:-1],
也就是從最後一個元素到第一個元素複製一遍,即倒序。
http://www.cnblogs.com/mxh1099/p/5804064.html

# 實現一個鏈表類,只有一個值val和一個指向下一個節點的next'指針'
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    # 返回從尾部到頭部的列表值序列,例如[1,2,3]
    def printListFromTailToHead(self, listNode):
        # @listNode: 頭結點
        # write code here
        l = []
        while listNode:
            l.append(listNode.val)
            listNode = listNode.next
        return l[::-1] 
# 實例化
# 創建鏈表 a->b->c
a = ListNode(1)
b = ListNode(2)
c = ListNode(3)
a.next = b
b.next = c

if __name__=='__main__':
    demo = Solution()
    print(demo.printListFromTailToHead(a))

02–鏈表中倒數第K個結點**

輸入一個鏈表,輸出該鏈表中倒數第k個結點。
思路: 先計算出所有的節點n,倒數第k個節點即是從前往後第n-k+1個節點

class Solution:
    def FindKthToTail(self, head, k):
        if  k<=0 or head==None:
            return None
        count=0
        p=head
        while p!=None:
            count+=1 # 算出鏈表節點數
            p=p.next
        if k>count:
            return None
        number=count-k+1  #需要走的步數
        cnt=0
        p=head
        while p!=None:
            cnt=cnt+1
            if cnt==number:
                return p
            p=p.next

思路2爲了能夠只遍歷一次就能找到倒數第k個節點,可以定義兩個指針:

(1)第一個指針從鏈表的頭指針開始遍歷向前走k-1,第二個指針保持不動;

(2)從第k步開始,第二個指針也開始從鏈表的頭指針開始遍歷;

(3)由於兩個指針的距離保持在k-1,當第一個(走在前面的)指針到達鏈表的尾結點時,第二個指針(走在後面的)指針正好是倒數第k個結點。

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def FindKthToTail(self, head, k):
        if k<=0 or head==None:
            return None
        else:
            count=0
            p=head
            mark=False
            ans=head #第二個指針
            while p!=None:
                count=count+1
                if count>k:
                    ans=ans.next
                p=p.next
            if count<k:
                ans=None
            return ans

03–反轉鏈表

輸入一個鏈表,反轉鏈表後,輸出新鏈表的表頭。
思考:反轉後新鏈表的表頭是不是是原始鏈表的最後一個,先給定一個空的鏈表newList,然後判斷傳入的鏈表head是不是空鏈表或者鏈表元素只有一個,如果是,直接返回就可以。如果不是,則對鏈表進行迭代,然後給一個臨時變量temp存儲head.next,然後改變head.next的指向newList,然後把head賦值給newList,接着讓head等於臨時變量temp,就這樣一直迭代完整個鏈表,返回newList就可以
在這裏插入圖片描述

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # 返回ListNode
    def ReverseList(self, head):
        if not head or not head.next:
            return head
        last=None
        while head:
            tmp=head.next
            head.next=last
            last=head
            head=tmp
        return last

04–合併兩個排序鏈表

輸入兩個單調遞增的鏈表,輸出兩個鏈表合成後的鏈表,當然我們需要合成後的鏈表滿足單調不減規則。
思路> 同步遍歷,先找到鏈表中頭結點比較小的作爲頭結點 每一次遍歷要比較節點大小
還要判斷兩個節點長短不一致,

在這裏插入圖片描述

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # 返回合併後列表
    def Merge(self, pHead1, pHead2):
        dummy=ListNode(0)
        pHead=dummy
        while pHead1 and pHead2:
            if pHead1.val>=pHead2.val:
                dummy.next=pHead2
                pHead2=pHead2.next
            else:
                dummy.next=pHead1
                pHead1=pHead1.next
            dummy=dummy.next
        if pHead1:
            dummy.next=pHead1
        else:
            dummy.next=pHead2
        return pHead.next
        # write code here

05-複雜鏈表的複製

輸入一個複雜鏈表(每個節點中有節點值,以及兩個指針,一個指向下一個節點,另一個特殊指針指向任意一個節點),返回結果爲複製後複雜鏈表的head。(注意,輸出結果中請不要返回參數中的節點引用,否則判題程序會直接返回空)
題目描述
輸入一個複雜鏈表(每個節點中有節點值,以及兩個指針,一個指向下一個節點,另一個特殊指針指向任意一個節點),返回結果爲複製後複雜鏈表的head。(注意,輸出結果中請不要返回參數中的節點引用,否則判題程序會直接返回空)
題目分析:

1.如果鏈表爲空鏈表,則返回本身即可
2.如果非空 需要進行復制操作,如果沒有特殊指針,只需要複製next我相信大家都能很快做出來,但是加上特殊指針這就需要一定技巧,因爲特殊指針隨便指,而你每次找特殊指針所指的節點都需要從頭開始遍歷找起,這顯然複雜度高達O(n²)

方法1:

在不使用輔助空間的情況下實現O(N)的時間效率。

  1. 把複製的結點鏈接在原始鏈表的每一對應結點後面

  2. 把複製的結點的random指針指向被複制結點的random指針的下一個結點

  3. 拆分成兩個鏈表,奇數位置爲原鏈表,偶數位置爲複製鏈表,注意複製鏈表的最後一個結點的next指針不能跟原鏈表指向同一個空結點None,next指針要重新賦值None(判定程序會認定你沒有完成複製)

原文:https://blog.csdn.net/jiangjiang_jian/article/details/81490693
https://blog.csdn.net/qq_33431368/article/details/79296360

如圖
首先第一步 複製原來的鏈表,順次連接形成新鏈表

在這裏插入圖片描述

 cloNode = pHead
        while cloNode:
            #完成第一步的核心操作
            node = RandomListNode(cloNode.label)
            node.next = cloNode.next
            cloNode.next = node
              cloNode = node.next #下一次操作

第二步,利用原節點的random指向,來用複製的相應節點的random

  cloNode = pHead
        while cloNode:
            node = cloNode.next #指向複製的結點
            if cloNode.random: #如果原節點有特殊指針
                node.random = cloNode.random.next #則複製的節點的特殊指針指向原節點的特殊指針指向的下一個值  看圖更好理解一些
            cloNode = node.next

最後一步,將複製好的鏈表拆分出來,或者說將 偶數位的節點重新拆分合成新的鏈表,得到的就是複製的鏈表

在這裏插入圖片描述

 cloNode = pHead
        pHead = pHead.next
        while cloNode.next:
            #完成第三步的核心操作 此時節點指向隔了一個節點的節點
            node = cloNode.next
            cloNode.next = node.next
            
            cloNode = node #下一個節點的操作

這個操作其實就是將兩個鏈表順次全都拆分出來,一個很關鍵的步驟 pHead = pHead.next 如果沒有這句話,最後得到的pHead就是原鏈表的開頭了。

總程序如下:

    # -*- coding:utf-8 -*-
    # class RandomListNode:
    #     def __init__(self, x):
    #         self.label = x
    #         self.next = None
    #         self.random = None
    class Solution:
        # 返回 RandomListNode
        def Clone(self, pHead):
            # write code here
            if not pHead:
                return pHead
            cloNode = pHead
            while cloNode:
                node = RandomListNode(cloNode.label)
                node.next = cloNode.next
                cloNode.next = node
                cloNode = node.next
            cloNode = pHead
            while cloNode:
                node = cloNode.next
                if cloNode.random:
                    node.random = cloNode.random.next
                cloNode = node.next
            cloNode = pHead
            pHead = pHead.next
            while cloNode.next:
                node = cloNode.next
                cloNode.next = node.next
                cloNode = node
            return pHead

方法2:遞歸

class Solution:
    def Clone(self, head):
        if not head: return
        newNode = RandomListNode(head.label)
        newNode.random = head.random
        newNode.next = self.Clone(head.next)
        return newNode

方法3:

實際上我們可以通過空間換取時間,將原始鏈表和複製鏈表的結點通過哈希表對應起來,這樣查找的時間就從O(N)變爲O(1)。具體如下:

複製原始鏈表上的每個結點N創建N’,然後把這些創建出來的結點用pNext連接起來。同時把<N,N’>的配對信息方法一個哈希表中;然後設置複製鏈表中的每個結點的pSibling指針,如果原始鏈表中結點N的pSibling指向結點S,那麼在複製鏈表中,對應的N’應該指向S’。

時間複雜度:O(N)

class Solution:
    def Clone(self, head):
        nodeList = []     #存放各個節點
        randomList = []   #存放各個節點指向的random節點。沒有則爲None
        labelList = []    #存放各個節點的值
 
        while head:
            randomList.append(head.random)
            nodeList.append(head)
            labelList.append(head.label)
            head = head.next
        #random節點的索引,如果沒有則爲1   
        labelIndexList = map(lambda c: nodeList.index(c) if c else -1, randomList)
 
        dummy = RandomListNode(0)
        pre = dummy
        #節點列表,只要把這些節點的random設置好,順序串起來就ok了。
        nodeList=map(lambda c:RandomListNode(c),labelList)
        #把每個節點的random綁定好,根據對應的index來綁定
        for i in range(len(nodeList)):
            if labelIndexList[i]!=-1:
                nodeList[i].random=nodeList[labelIndexList[i]]
        for i in nodeList:
            pre.next=i
            pre=pre.next
        return dummy.next

06–二叉搜索樹與雙向鏈表

輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的雙向鏈表。要求不能創建任何新的結點,只能調整樹中結點指針的指向。

題目描述
輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的雙向鏈表。要求不能創建任何新的結點,只能調整樹中結點指針的指向。

題目分析: 二叉搜索樹 根節點大於左節點, 根節點小於右節點
比如將二元查找樹


轉換成雙向鏈表(雙向鏈表也叫雙鏈表,是鏈表的一種,它的每個數據結點中都有兩個指針,分別指向直接後繼和直接前驅。所以,從雙向鏈表中的任意一個結點開始,都可以很方便地訪問它的前驅結點和後繼結點。一般我們都構造雙向循環鏈表。)下面是數組,鏈表的一些定義操作
https://www.cnblogs.com/skywang12345/p/3561803.html

在這裏插入圖片描述
思路:
1.二叉樹中序遍歷的結果與鏈表的順序一致,所以可以採用中序遍歷的方法來修改二叉樹的指針

2.該題的關鍵是,如何將左子樹的最大值與右子樹的最小值通過根root連接起來,比如題目的8和12,這也是細節部分

3.寫遞歸程序最重要的是弄明白遞歸進入的條件、遞歸返回的狀態,如果遞歸進入時改變了環境,返回時應當恢復環境,就像棧的操作一樣

4.使用指針變量時,要記得初始化

5.該算法沒有返回鏈表頭,而是返回了root。
在這裏插入圖片描述

用中序遍歷和遞歸,且以這張圖爲第一步,後續的左右子樹均按照圖示的思路來做,並且前後不用任何中間節點。但慢慢發現,如果用遞歸,在不新建任何中間節點的情況下,我只能實現到:46810161412,並且圖示提供的思路也不夠精確。
遂求助網絡,但得到的解法均需要新建輔助節點,且絕大多數代碼不夠簡練。在牛客網該題下大家的討論中倒是有不錯的思路,只是沒有配文的情況下還需要點時間理解。鑑於自己沒查到該題精簡且詳細的解題思路,我就露個拙,實現Python解法,並配上我的理解。

思路

核心算法依舊是中序遍歷 不是從根節點開始,而是從中序遍歷得到的第一個節點開始
定義兩個輔助節點listHead(鏈表頭節點)、listTail(鏈表尾節點)。事實上,二叉樹只是換了種形式的鏈表;listHead用於記錄鏈表的頭節點,用於最後算法的返回;listTail用於定位當前需要更改指向的節點。瞭解了listHead和listTail的作用,代碼理解起來至少順暢80%。
提供我畫的算法的過程圖,有點醜,但有助於理解(幫你們畫了,你們就不用畫啦),另外圖中右上角步驟三應該是“2”標紅,“2”和“1”中間的連接爲單線黑~~~

在這裏插入圖片描述
https://blog.csdn.net/jiangjiang_jian/article/details/81637574

class Solution:
    def __init__(self):
        self.listHead = None
        self.listTail = None
    def Convert(self, pRootOfTree):
        if pRootOfTree==None:
            return
        self.Convert(pRootOfTree.left)
        if self.listHead==None:
            self.listHead = pRootOfTree
            self.listTail = pRootOfTree
        else:
            self.listTail.right = pRootOfTree
            pRootOfTree.left = self.listTail
            self.listTail = pRootOfTree
        self.Convert(pRootOfTree.right)
        return self.listHead

在這裏插入圖片描述在這裏插入圖片描述

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def Convert(self, pRootOfTree):
        if not pRootOfTree:
            return None
         
        p = pRootOfTree
         
        stack = []
        resStack = []
         
        while p or stack:
            if p:
                stack.append(p)
                p = p.left
            else:
                node = stack.pop()
                resStack.append(node)
                p = node.right
             
        resP = resStack[0]
        while resStack:
            top = resStack.pop(0)
            if resStack:
                top.right = resStack[0]
                resStack[0].left = top
         
        return resP
遞歸版本

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def Convert(self, root):
        if not root:
            return None
        if not root.left and not root.right:
            return root
         
        # 將左子樹構建成雙鏈表,返回鏈表頭
        left = self.Convert(root.left)
        p = left
         
        # 定位至左子樹的最右的一個結點
        while left and p.right:
            p = p.right
         
        # 如果左子樹不爲空,將當前root加到左子樹鏈表
        if left:
            p.right = root
            root.left = p
         
        # 將右子樹構造成雙鏈表,返回鏈表頭
        right = self.Convert(root.right)
        # 如果右子樹不爲空,將該鏈表追加到root結點之後
        if right:
            right.left = root
            root.right = right
             
        return left if left else root

07–兩個鏈表的第一個公共節點

輸入兩個鏈表,找出它們的第一個公共結點。
次將鏈表中的元素壓入兩個棧中,然後每次從兩個棧中拋出一個元素,直到拋出的結點相同時返回
後面的元素都是公共的

class Solution:
    def FindFirstCommonNode(self, pHead1, pHead2):
        # write code here
        lst1 = []
        lst2 = []
        result = []
 
        if not pHead1 or not pHead2:
            return None
 
        p1 = pHead1
        p2 = pHead2
 
        while p1:
            lst1.append(p1)
            p1 = p1.next
        while p2:
            lst2.append(p2)
            p2 = p2.next
 
        while lst1 and lst2:
            node1 = lst1.pop()
            node2 = lst2.pop()
            if node1 == node2:
                result.append(node1)
         
        if result:
            node = result.pop()
            return node

思路2:
直接把第一個鏈表丟到set裏面,然後遍歷第二個鏈表,找到第一個一樣的節點,時間O(M+N)

  # -*- coding:utf-8 -*-
    # class ListNode:
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    class Solution:
        def FindFirstCommonNode(self, pHead1, pHead2):
            result_set = set()
            while pHead1:
                result_set.add(pHead1)
                pHead1 = pHead1.next
            while pHead2:
                if pHead2 in result_set:
                    return pHead2
                pHead2 = pHead2.next

09–刪除鏈表中重複的節點

在一個排序的鏈表中,存在重複的結點,請刪除該鏈表中重複的結點,重複的結點不保留,返回鏈表頭指針。 例如,鏈表1->2->3->3->4->4->5 處理後爲 1->2->5

首先添加一個頭節點,以方便碰到第一個,第二個節點就相同的情況

2.設置 pre ,last 指針, pre指針指向當前確定不重複的那個節點,而last指針相當於工作指針,一直往後面搜索。使用3個指針,一個指向前一個節點last,一個指向當前節點p,一個指向下一個節點p->next,噹噹前節點跟後一個節點相等時,不斷往後遍歷,找到第一個不等於當前節點的節點;然後用last
指向它;噹噹前節點跟後一個不相等時,將last 後移指向p,p後移一位

class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None
class Solution:
    def deleteDuplication(self, pHead):
        # write code here
        if pHead == None or pHead.next == None:
            return pHead
        new_head = ListNode(-1)
        new_head.next = pHead# # 因爲需要兩個指針,一個指着重複結點上一個結點,一個指着重複結點後一個值。
        pre = new_head
        p = pHead
        nex = None
        while p != None and p.next != None:
            nex = p.next
            if p.val == nex.val:
                while nex != None and nex.val == p.val:
                    nex = nex.next
                pre.next = nex
                p = nex
            else:
                pre = p
                p = p.next
        return new_head.next
鏈接:https://www.nowcoder.com/questionTerminal/fc533c45b73a41b0b44ccba763f866ef?f=discussion
來源:牛客網

先不管三七二十一把所有節點的值放到一個列表中,再篩選出值數量爲1的值。
再新建一個鏈表返回即可。很暴力。

class Solution:
    def deleteDuplication(self, pHead):
        res = []
        while pHead:
            res.append(pHead.val)
            pHead = pHead.next
        res = list(filter(lambda c: res.count(c) == 1, res))
        dummy = ListNode(0)
        pre = dummy
        for i in res:
            node = ListNode(i)
            pre.next = node
            pre = pre.next
        return dummy.next

09-反轉鏈表

題目描述
輸入一個鏈表,反轉鏈表後,輸出新鏈表的表頭。
鏈表是通過一個個節點組成的,每個節點都包含了稱爲cargo的基本單元,它也是一種遞歸的數據結構。它能保持數據之間的邏輯順序,但存儲空間不必按照順序存儲。
如圖:

在這裏插入圖片描述

鏈表的基本元素有:

節點:每個節點有兩個部分,左邊部分稱爲值域,用來存放用戶數據;右邊部分稱爲指針域,用來存放指向下一個元素的指針。
head:head節點永遠指向第一個節點 tail: tail永遠指向最後一個節點 None:鏈表中最後一個節點的指針域爲None值

思路1:
因爲鏈表是有head和tail,而他們是有一個方向的,因此我們想直接進行類似list[::-1]這種反轉就不是太方便。在下面的算法中,我們通過將鏈表截斷,而後再拼接的方式進行反轉。

以{1,2,3}鏈表作爲例子,來說明下面算法中while迭代的流程(手工debug…)

1.將{2,3}的地址指向給tmp
2.將last=None指向pHead.next,這個時候pHead鏈表就被截斷了,pHead只剩下了1,因爲他的下一步指向了None
3.將此時的pHead,也就是1指向給last,這時候last爲{1}
4.將tmp={2,3}指向給pHead,此時這輪迭代結束,開啓下一輪. 這時,pHead是{2,3},last是{1}

5.將{3}指向給tmp
6.將{1}指向給pHead.next,也就是2的下一步值,因此這時候pHead就變成了{2,1}
7.將{2,1}指向給last
8.將{3}指向給pHead,此時這輪迭代結束,開啓下一輪. 這時,pHead是{3},last是{2,1}

9.將None指向了tmp
10.將{2,1}指向給pHead.next,也就是{3}的下一步值,這個時候pHead就變成了{3,2,1}
11.將{3,2,1}指向給last
12.將None指向給pHead,此時這輪迭代結束,while迭代結束。 這時pHead是{None},last是{3,2,1}
https://www.jianshu.com/p/e385d9c06672
根據下圖,先給定一個空的鏈表newList,然後判斷傳入的鏈表head是不是空鏈表或者鏈表元素只有一個,如果是,直接返回就可以。如果不是,則對鏈表進行迭代,然後給一個臨時變量temp存儲head.next,然後改變head.next的指向newList,然後把head賦值給newList,接着讓head等於臨時變量temp,就這樣一直迭代完整個鏈表,返回newList就可以
在這裏插入圖片描述

class Solution:
    # 返回ListNode
    def ReverseList(self, pHead):
        if not pHead or not pHead.next:
            return pHead
        last =None
        while pHead:
            tmp = pHead.next#將下一步的地址指向給tmp
            pHead.next=last#將一個新的鏈表指向給舊鏈表pHead,這個時候就把pHead截斷了,只剩下前面的鏈表值
            last=pHead#將舊鏈表的地址指向給新鏈表
            pHead=tmp#將舊鏈表原來的下一步只指向給pHead
        return last


思路2:–遞歸

思路:假設鏈表爲[1,2,3,4,5]先迭代到鏈表末尾5,然後從5開始依次反轉整個鏈表
如下圖所示,先迭代待最後一位5,並且設置一個新的節點newList作爲反轉後鏈表的頭結點,由於整個鏈表反轉後的頭就是最後一個數,所以newList存放的一直是反轉後的頭結點的地址,將head指向的地址賦值給head->next->next指針,並且一定要記得讓head->next
=NULL,也就是斷開現在指針的鏈接,否則新的鏈表形成了環,下一層head->next->next賦值的時候會覆蓋後續的值。依次反轉。
在這裏插入圖片描述

class Solution:
    # 返回ListNode
    def ReverseList(self, head):
        if head==None or head.next==None:
            return head
        newlist=ReverseList(head.next)
        head.next.next=head
        head.next=None
        return newlist
 

兩個鏈表的第一個公共節點

題目描述
輸入兩個鏈表,找出它們的第一個公共結點。

題目分析:
鏈表兩個長度十分相等

鏈接:https://www.nowcoder.com/questionTerminal/6ab1d9a29e88450685099d45c9e31e46
來源:牛客網

依次將鏈表中的元素壓入兩個棧中,然後每次從兩個棧中拋出一個元素,直到拋出的結點相同時返回
後面的元素都是公共的
class Solution:
    def FindFirstCommonNode(self, pHead1, pHead2):
        # write code here
        lst1 = []
        lst2 = []
        result = []
 
        if not pHead1 or not pHead2:
            return None
 
        p1 = pHead1
        p2 = pHead2
 
        while p1:
            lst1.append(p1)
            p1 = p1.next
        while p2:
            lst2.append(p2)
            p2 = p2.next
 
        while lst1 and lst2:
            node1 = lst1.pop()
            node2 = lst2.pop()
            if node1 == node2:
                result.append(node1)
         
        if result:
            node = result.pop()
            return node

思路2:
直接把第一個鏈表丟到set裏面,然後遍歷第二個鏈表,找到第一個一樣的節點,時間O(M+N)

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def FindFirstCommonNode(self, pHead1, pHead2):
        result_set = set()
        while pHead1:
            result_set.add(pHead1)
            pHead1 = pHead1.next
        while pHead2:
            if pHead2 in result_set:
                return pHead2
            pHead2 = pHead2.next
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章