1. 程式人生 > >劍指offer系列——刪除連結串列中重複的結點,二叉樹的下一個結點,對稱的二叉樹

劍指offer系列——刪除連結串列中重複的結點,二叉樹的下一個結點,對稱的二叉樹

刪除連結串列中重複的結點

題目描述

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

解題思路:

法一:連結串列裡面所有的數存在一個列表裡面,然後把列表裡面只出現一次的數提取出來,再新建一個連結串列放進去

法二:只用一次遍歷,兩個指標,一個指向重複結點上一個結點,一個指向重複結點後一個值。前後比較是否相等。

程式碼:

法一:

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def deleteDuplication(self, pHead):
        # write code here
        res = []
        while pHead:
            res.append(pHead.val)
            pHead = pHead.next
        #filter 與map相似,但是filter返回的是bool去除重複進行判斷
        res = list(filter(lambda c:res.count(c) == 1, res))
        newlist = ListNode(0)
        pre = newlist
        for i in res:
            node = ListNode(i)
            pre.next = node
            pre = pre.next
        return newlist.next
         

法二:

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def deleteDuplication(self, pHead):
        # write code here
        #檢查空或只有一個元素
        if pHead is None or pHead.next is None:
            return pHead
        #防止第一個就是重複結點,創造一個新的頭節點。
        first = ListNode(-1)
        first.next = pHead 
        last = first 
        while pHead and pHead.next:
            if pHead.val ==pHead.next.val:
                val = pHead.val #儲存值
                while pHead and val==pHead.val:
                    pHead = pHead.next
                last.next = pHead #最後一個指標指向個數
            else:
                last = pHead
                pHead = pHead.next
        return first.next

二叉樹的下一個結點

題目描述

給定一個二叉樹和其中的一個結點,請找出中序遍歷順序的下一個結點並且返回。注意,樹中的結點不僅包含左右子結點,同時包含指向父結點的指標。

解題思路:

1.二叉樹為空,則返回空;

2.節點右孩子存在,則設定一個指標從該節點的右孩子出發,一直沿著指向左子結點的指標找到的葉子節點即為下一個節點;

3.節點不是根節點。如果該節點是其父節點的左孩子,則返回父節點;否則繼續向上遍歷其父節點的父節點,重複之前的判斷,返回結果。

首先知道中序遍歷的規則是:左根右,然後作圖

 

結合圖,我們可發現分成兩大類:1、有右子樹的,那麼下個結點就是右子樹最左邊的點;(eg:D,B,E,A,C,G) 2、沒有右子樹的,也可以分成兩類,a)是父節點左孩子(eg:N,I,L) ,那麼父節點就是下一個節點 ; b)是父節點的右孩子(eg:H,J,K,M)找他的父節點的父節點的父節點...直到當前結點是其父節點的左孩子位置。如果沒有eg:M,那麼他就是尾節點。

程式碼:

# -*- coding:utf-8 -*-
# class TreeLinkNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#         self.next = None
class Solution:
    def GetNext(self, pNode):
        # write code here
        if not pNode:
            return None
        if pNode.right:#右存在,右子樹的最左邊
            pNode = pNode.right 
            while pNode.left:
                pNode = pNode.left
            return pNode
        else: 
            while pNode.next:#不是根結點
                if pNode == pNode.next.left:#左子樹上,下一節點是父節點
                    return pNode.next
                pNode = pNode.next
        return None 
        

對稱的二叉樹

題目描述

請實現一個函式,用來判斷一顆二叉樹是不是對稱的。注意,如果一個二叉樹同此二叉樹的映象是同樣的,定義其為對稱的。

解題思路:

遞迴來做。根不變,左右子樹交換。

程式碼:

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def isSymmetrical(self, pRoot):
        # write code here
        return self.IsSymmetrical(pRoot,pRoot)
    def IsSymmetrical(self, pRoot1,pRoot2):
        if pRoot1 == None and pRoot2 == None:
            return True
        if pRoot1 == None or pRoot2 == None:
            return False
        if pRoot1.val != pRoot2.val:
            return False
        return self.IsSymmetrical(pRoot1.left, pRoot2.right) and self.IsSymmetrical(pRoot1.right,pRoot2.left)