PHP之從反向刪除單鏈表元素的問題談起
在完成一個單鏈表的刪除指定元素的題目中,我發現了一件神奇的事情,php對象賦值給另外一個變量後,可以如同引用傳值一般繼續利用新的變量來實現鏈表的鏈接。
後面經過查證後發現:
PHP7.0版本除了對象,資源之外,其餘數據類型均已實現寫時複製
嘗試寫了一個簡單測試代碼,如下所示:
<?php
$obj1 = new stdClass();
$obj1->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的算法題也真的是腦力的擼鐵呢。