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

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的算法題也真的是腦力的擼鐵呢。

原文地址https://www.cnblogs.com/freephp/p/12593774.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章