PHP之從反向刪除單鏈表元素的問題談起
阿新 • • 發佈:2020-03-29
在完成一個單鏈表的刪除指定元素的題目中,我發現了一件神奇的事情,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的演算法題也真的是腦力的擼