PHPer也刷《剑指Offer》之链表

本文通过几个典型题目,包括从尾到头打印链表、寻找倒数第k个节点等,详细解析了链表的基本操作及其实现方法,并提供PHP代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

温故知新

链表由一个一个的作为节点的对象构成的,每一个节点都有指向下一个节点的指针,最后一个节点的指针域指向空。每个节点可以存储任何数据类型。

根据类型可以分为单链表、双链表、环形链表、复杂链表等等结构,这些结构又可以相互组合。

对这部分基础内容不太熟悉的同学可以看我之前写的实战PHP数据结构基础之单链表 以及实战PHP数据结构基础之双链表

《剑指offer》中链表相关题目

俗话说光说不练假把式,既然学习了链表的基础概念和基本操作 那我们一定要找些题目巩固下,下面来看《剑指offer》中的相关题目。

输入一个链表,从尾到头打印链表每个节点的值

题目分析:这道题还是比较简单的,考察的基础知识,难度系数一颗星。 考察考点:链表。

解答示例:

function printListFromTailToHead($head)
{
    // write code here
    $list = [];
    $currentNode = $head;
    while ($currentNode) {
        $list[] = $currentNode->val;
        $currentNode = $currentNode->next;
    }
    return array_reverse($list);
}
复制代码

输入一个链表,输出该链表中倒数第k个结点。

题目分析:依然考察的基础知识,难度系数一颗星。 考察考点:链表。

解答示例:

function FindKthToTail($head, $k)
{
    $currentNode = $head;
    $data = [];
    if ($currentNode) {
        while ($currentNode) {
            $data[] = $currentNode;
            $currentNode = $currentNode->next;
        }
        return $data[count($data) - $k];
    }
    return null;
}
复制代码

输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。

题目分析:合并两个排序的链表,需要分别比较两个链表的每个值,然后改变next指针。 考察考点:链表。

解答示例:

/*递归解法*/
/*class ListNode{
    var $val;
    var $next = NULL;
    function __construct($x){
        $this->val = $x;
    }
}*/
function Merge($pHead1, $pHead2)
{
    if (is_null($pHead1)) {
        return $pHead2;
    } elseif (is_null($pHead2)) {
        return $pHead1;
    }
    $merged = new ListNode(null);
    if ($pHead1->val < $pHead2->val) {
        $merged->val = $pHead1->val;
        $merged->next = Merge($pHead1->next, $pHead2);
    } else {
        $merged->val = $pHead2->val;
        $merged->next = Merge($pHead1, $pHead2->next);
    }
    return $merged;
}
复制代码

在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。例如,链表1->2->3->3->4->4->5 处理后为 1->2->5

题目分析:保存相同的值,然后判断相同节点改变前一个节点的next指针即可。 考察考点:链表。

解答示例:

/*class ListNode{
    var $val;
    var $next = NULL;
    function __construct($x){
        $this->val = $x;
    }
}*/
function deleteDuplication($pHead)
{
    $currentNode = $pHead;
    $prev = null;
    if ($currentNode) {
        while ($currentNode) {
            if ($currentNode->val == $currentNode->next->val) {
                $sameVal = $currentNode->val;
                while ($currentNode->val == $sameVal) {
                    $currentNode = $currentNode->next;
                }
                //头节点
                if (empty($prev)) {
                    $pHead = $currentNode;
                    $currentNode = $pHead;
                } else {
                    //正常节点
                    $prev->next = $currentNode;
                }
            } else {
                $prev = $currentNode;
                $currentNode = $currentNode->next;
            }
        }
    }
    return $pHead;
}
复制代码

两个链表的第一个公共节点

解答示例:


/*class ListNode{
    var $val;
    var $next = NULL;
    function __construct($x){
        $this->val = $x;
    }
}*/
function FindFirstCommonNode($pHead1, $pHead2)
{
    $currentNode1 = $pHead1;
    $currentNode2 = $pHead2;
    if ($currentNode1 === $currentNode2) {
        return $pHead1;
    }
    while ($currentNode1 !== $currentNode2) {
        $currentNode1 = ($currentNode1 == null ? $pHead2 : $currentNode1->next);
        $currentNode2 = ($currentNode2 == null ? $pHead1 : $currentNode2->next);
    }
    return $currentNode1;
}
复制代码
更多题目解答

PHP基础数据结构专题系列目录地址:github.com/... 主要使用PHP语法总结基础的数据结构和算法。还有我们日常PHP开发中容易忽略的基础知识和现代PHP开发中关于规范、部署、优化的一些实战性建议,同时还有对Javascript语言特点的深入研究。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值