开发者社区> 优惠码发放> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

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

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
centos下 Apache、php、mysql默认安装路径
apache: 如果采用RPM包安装,安装路径应在 /etc/httpd目录下 apache配置文件:/etc/httpd/conf/httpd.conf Apache模块路径:/usr/sbin/apachectl web目录:/var/www/html 如果采用源代码安装,一般默认安装在/usr/local/apache2目录下 php: 如果采用RPM包安装,安装路
3018 0
+关注
优惠码发放
阿里云优惠码阿里云推荐券bieryun.com
569
文章
4
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载