PHPer也刷《劍指Offer》之連結串列

蕭瀟發表於2018-06-22

溫故知新

連結串列由一個一個的作為節點的物件構成的,每一個節點都有指向下一個節點的指標,最後一個節點的指標域指向空。每個節點可以儲存任何資料型別。

根據型別可以分為單連結串列、雙連結串列、環形連結串列、複雜連結串列等等結構,這些結構又可以相互組合。

對這部分基礎內容不太熟悉的同學可以看我之前寫的實戰PHP資料結構基礎之單連結串列 以及實戰PHP資料結構基礎之雙連結串列

《劍指offer》中連結串列相關題目

俗話說光說不練假把式,既然學習了連結串列的基礎概念和基本操作 那我們一定要找些題目鞏固下,下面來看《劍指offer》中的相關題目。

輸入一個連結串列,從尾到頭列印連結串列每個節點的值

題目分析:這道題還是比較簡單的,考察的基礎知識,難度係數一顆星。 考察考點:連結串列。

解答示例:

function printListFromTailToHead($head)
{
    // write code here
    $list = [];
    $currentNode = $head;
    while ($currentNode) {
        $list[] = $currentNode->val;
        $currentNode = $currentNode->next;
    }
    return array_reverse($list);
}
複製程式碼

輸入一個連結串列,輸出該連結串列中倒數第k個結點。

題目分析:依然考察的基礎知識,難度係數一顆星。 考察考點:連結串列。

解答示例:

function FindKthToTail($head, $k)
{
    $currentNode = $head;
    $data = [];
    if ($currentNode) {
        while ($currentNode) {
            $data[] = $currentNode;
            $currentNode = $currentNode->next;
        }
        return $data[count($data) - $k];
    }
    return null;
}
複製程式碼

輸入兩個單調遞增的連結串列,輸出兩個連結串列合成後的連結串列,當然我們需要合成後的連結串列滿足單調不減規則。

題目分析:合併兩個排序的連結串列,需要分別比較兩個連結串列的每個值,然後改變next指標。 考察考點:連結串列。

解答示例:

/*遞迴解法*/
/*class ListNode{
    var $val;
    var $next = NULL;
    function __construct($x){
        $this->val = $x;
    }
}*/
function Merge($pHead1, $pHead2)
{
    if (is_null($pHead1)) {
        return $pHead2;
    } elseif (is_null($pHead2)) {
        return $pHead1;
    }
    $merged = new ListNode(null);
    if ($pHead1->val < $pHead2->val) {
        $merged->val = $pHead1->val;
        $merged->next = Merge($pHead1->next, $pHead2);
    } else {
        $merged->val = $pHead2->val;
        $merged->next = Merge($pHead1, $pHead2->next);
    }
    return $merged;
}
複製程式碼

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

題目分析:儲存相同的值,然後判斷相同節點改變前一個節點的next指標即可。 考察考點:連結串列。

解答示例:

/*class ListNode{
    var $val;
    var $next = NULL;
    function __construct($x){
        $this->val = $x;
    }
}*/
function deleteDuplication($pHead)
{
    $currentNode = $pHead;
    $prev = null;
    if ($currentNode) {
        while ($currentNode) {
            if ($currentNode->val == $currentNode->next->val) {
                $sameVal = $currentNode->val;
                while ($currentNode->val == $sameVal) {
                    $currentNode = $currentNode->next;
                }
                //頭節點
                if (empty($prev)) {
                    $pHead = $currentNode;
                    $currentNode = $pHead;
                } else {
                    //正常節點
                    $prev->next = $currentNode;
                }
            } else {
                $prev = $currentNode;
                $currentNode = $currentNode->next;
            }
        }
    }
    return $pHead;
}
複製程式碼

兩個連結串列的第一個公共節點

解答示例:


/*class ListNode{
    var $val;
    var $next = NULL;
    function __construct($x){
        $this->val = $x;
    }
}*/
function FindFirstCommonNode($pHead1, $pHead2)
{
    $currentNode1 = $pHead1;
    $currentNode2 = $pHead2;
    if ($currentNode1 === $currentNode2) {
        return $pHead1;
    }
    while ($currentNode1 !== $currentNode2) {
        $currentNode1 = ($currentNode1 == null ? $pHead2 : $currentNode1->next);
        $currentNode2 = ($currentNode2 == null ? $pHead1 : $currentNode2->next);
    }
    return $currentNode1;
}
複製程式碼

更多題目解答

PHP基礎資料結構專題系列目錄地址:github.com/... 主要使用PHP語法總結基礎的資料結構和演算法。還有我們日常PHP開發中容易忽略的基礎知識和現代PHP開發中關於規範、部署、優化的一些實戰性建議,同時還有對Javascript語言特點的深入研究。

相關文章