1. 程式人生 > >PHP之從反向刪除單鏈表元素的問題談起

PHP之從反向刪除單鏈表元素的問題談起

在完成一個單鏈表的刪除指定元素的題目中,我發現了一件神奇的事情,php物件賦值給另外一個變數後,可以如同引用傳值一般繼續利用新的變數來實現連結串列的連結。 後面經過查證後發現: > PHP7.0版本除了物件,資源之外,其餘資料型別均已實現寫時複製 嘗試寫了一個簡單測試程式碼,如下所示: ``` val = 3; $obj1->next = null; $obj2 = $obj1; $obj2->next = array(); $obj2 = null; var_dump($obj1); ``` 打印出的$obj1的結構裡面不會因為$obj2被賦值為null而讓$obj1成為null。 關於從後往前面刪除單鏈表元素的問題,原題如下: 給定一個連結串列,刪除連結串列的倒數第 n 個節點,並且返回連結串列的頭結點。 示例: 給定一個連結串列: 1->2->3->4->5, 和 n = 2. 當刪除了倒數第二個節點後,連結串列變為 1->2->3->5. 說明: 給定的 n 保證是有效的。 來源:力扣(LeetCode) 連結:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list 分析下來就是一個基礎單鏈表操作的變種題目,如果是從頭往後刪除的話,就是我們常見的刪除操作。所以唯一不同的就是順序問題,於是先定義獲取單鏈表長度的函式和刪除指定位置元素的函式,然後再呼叫的時候把從後往前的位置數改為從頭往後數的位置即可。 ``` /** * Definition for a singly-linked list. * class ListNode { * public $val = 0; * public $next = null; * function __construct($val) { $this->val = $val; } * } */ class Solution { /** * @param ListNode $head * @param Integer $n * @return ListNode */ function removeNthFromEnd($head, $n) { $length = getLength($head); $from_start_num = $length - $n; // if ($n == 1 && $length == 1) { // return null; // } // if ($from_start_num == 0 && $n === $length) { // return $head->next; // } $return_node_list = deleteLinkItem($head, $from_start_num); return $return_node_list; } } /** * @param $head * @param int $index * @return null */ function deleteLinkItem($head, $index = 1) { if (is_null($head)) { return null; } else { if ($index == 0) { return $head->next; } $i = 1; $current = $head; while($current->next != null) { if ($i == $index) { $tmp = $current->next; break; } $i++; $current = $current->next; } $current->next = $tmp->next; return $head; } } /** * @param $head * @param $node * @param int $index * @return mixed */ function getLength($head) { if (empty($head)) { return 0; } $i = 1; while($head->next != null) { $i++; $head = $head->next; } return $i; } ``` 唯一要注意的是,由於deleteLinkItem的$index是從1開始算的,和腳標起始0不同,假如是要刪除0下標(也就連結串列是第一個元素被刪除),那麼直接返回頭部節點的next即可,如程式碼中的這段: ``` if ($index == 0) { return $head->next; } ``` 總的來說解法中規中矩,沒有利用的PHP的黑魔法。越是自由度高的程式語言,對於演算法題來說越難真正鍛鍊到,所以往往需要自廢神功,當成靜態語言去玩。而下標看得讓人腦仁疼,看來即使是一道medium的演算法題也真的是腦力的擼