面试题18:删除链表节点

18.1 在 O(1) 时间内删除链表节点

<?php
header("content-type:text/html;charset=utf-8");
/*
 * 在 O(1) 时间内删除链表节点。 P119
 */
class ListNode{
    var $val;
    var $next = NULL;
    function __construct($x){
        $this->val = $x;
    }
}
function deleteNode($head,$deleteNode){
    if($head == null || $deleteNode == null){
        return false;
    }
    if($head->next == null){
        return null;
    }
    if($deleteNode->next == null){
        return traverseDelete($head);
    }
    else{
        $deleteNode->val = $deleteNode->next->val;
        $deleteNode->next = $deleteNode->next->next;
        return $head;
    }
}

function traverseDelete($head){
    $cur = $head;
    while ($cur->next->next != null){
        $cur = $cur->next;

    }
    $cur->next = null;
    return $head;
}

$head = new ListNode(1);
$head->next = new ListNode(2);
$head->next->next = new ListNode(3);
$head->next->next->next = new ListNode(4);
$head->next->next->next->next = new ListNode(5);
$deleteNode = $head->next->next->next->next;
print_r(deleteNode($head,$deleteNode));

18.2 删除链表中重复的结点

<?php
header("content-type:text/html;charset=utf-8");
/*
 * 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。
 * 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5。P122
 */
class ListNode{
    var $val;
    var $next = NULL;
    function __construct($x){
        $this->val = $x;
    }
}
function deleteDuplication($pHead)
{
    if($pHead == null || $pHead->next == null){
        return $pHead;
    }

    $next = $pHead->next;

    if($pHead->val == $next->val){  //若头结点与相邻的节点相等,就一直向下遍历到不等的地方,此时next就指向不等的结点
        while ($next != null && $pHead->val == $next->val){
            $next = $next->next;
        }
        return deleteDuplication($next); //以该不等的结点为头,继续向下遍历
    }
    else{
        $pHead->next = deleteDuplication($pHead->next);//若头结点与相邻的节点不等,那就看下一个结点。
    }

    return $pHead;

}

$head = new ListNode(1);
$head->next = new ListNode(1);
$head->next->next = new ListNode(2);
$head->next->next->next = new ListNode(3);
$head->next->next->next->next = new ListNode(3);
$head->next->next->next->next->next = new ListNode(4);
$head->next->next->next->next->next->next = new ListNode(5);
print_r(deleteDuplication($head));

原文地址:https://www.cnblogs.com/xlzfdddd/p/10162809.html

时间: 2024-11-11 18:31:32

面试题18:删除链表节点的相关文章

18 删除链表的节点/重复节点

题目描述:  题目一:在O(1)时间内删除链表节点 :在给定的单向链表的头指针和一个节点指针,定义一个函数在O(1)时间内删除该节点. //链表定义 struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } }; 注意:输入提供了要删除节点的指针!! 测试用例: 1)功能测试(从有多个节点的链表中删除中间.头.尾节点:从只有一个节点的链表中删除唯一的节点) 2)特殊输入测试

剑指offer---以O(1)时间删除链表节点

问题:删除链表节点 要求:以O(1)时间 对于删除指定索引的链表元素大家都很熟悉,思路一般是从头遍历链表直到指定索引位置删除元素,然后维护一下指针即可,时间复杂度O(n).代码如下: 1 // 删除position位置的数据,并返回 2 int List::erasePosition(int position){ 3 if(position<0 || position>(List::size()-1)){ 4 cout<<"position error, please c

lintcode 容易题:Delete Node in the Middle of Singly Linked List 在O(1)时间复杂度删除链表节点

题目: 在O(1)时间复杂度删除链表节点 给定一个单链表中的表头和一个等待被删除的节点(非表头或表尾).请在在O(1)时间复杂度删除该链表节点.并在删除该节点后,返回表头. 样例 给定 1->2->3->4,和节点 3,返回 1->2->4. 解题: 方法好贱,先把要删除节点后面一个节点的值赋给删除节点,这样需要删除节点就删除了,再把删除节点指向删除节点后面节点的节点 就像这样: node.val = node.next.val; node.next = node.next.

LeetCode之“链表”:在O(1)时间删除链表节点

下边讨论暂不包括尾节点. 一般来说,我们要删除链表中的一个节点是需要知道其上一节点的.但我们真的需要吗? 其实我们可以将待删节点的下一节点的值和指向的下一节点赋予待删节点,然后删除待删节点的下一节点.具体示例程序如下: 1 //O(1)时间删除链表节点,从无头单链表中删除节点 2 void deleteRandomNode(Node *cur) 3 { 4 assert(cur != NULL); 5 assert(cur->next != NULL); //不能是尾节点 6 Node* pNe

关于递归删除链表节点为什么不会断链问题解释

问题的由来:    当你第一次实现用递归实现链表删除功能的时候,是否有一丝丝的考虑过.这个问题呢?为什么对于非递归版本的删除必须要知道当前要删除节点的前驱,而需要对其前驱节点的next域指针进行修改.而递归删除却不需要呢?难道这样不会造成链表的断链吗? 好了.我们开始抽象出我们今天要解决的问题. 问题一: 递归实现链表节点的删除和非递归删除的区别是什么? 问题二: 为什么在使用递归删除的时候链表不会断链? 先给个代码,好根据代码模拟,不会空想. 函数的递归模型: 终止条件: f(L,x) = 不

【剑指offer】18.删除链表中重复节点

思路 实现 /* 说下大概思路: 与链表的其他题目类似,为了防止删除头结点的极端情况发生,先创建空结点dummy,使dummy指向传入的head结点. 然后创建cur的指针,指向链表的头部(即dummy). 接着对cur指针迭代,因为要对比cur(cur最初始的定义指向空结点)指针的下一个结点与下下一个结点的值是否相等,为了防止产生空指针异常,故退出迭代的条件为:cur.next != null && cur.next.next != null. 在迭代过程中,如果cur.next.val

在O(1)时间删除链表节点

按照以往的习惯,这种题我们需要遍历整个链表,找到需要删除节点的前一个节点,这样我们就可以操作删除的方法了,这种方法需要O(n)的时间复杂度,但这里要求我们在O(1)的时间下完成.我们只能想其他的方法. 算法思想:其实我们也不需要知道删除节点前一个节点.我们的做法是将删除节点的后边一个节点的值赋给要删除的节点(即把要删除节点的值覆盖),然后将删除节点后边的节点删除(delete)即可.其中我们还需要检查要删除节点的位置,具体问题具体分析,要做到全面. 算法实现: 1 typedef struct

剑指Offer之在O(1)时间删除链表节点

题目描述 给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间删除该节点. 解题思路 在单向链表中删除一个节点,最常规的做法无疑是从链表的头结点开始,顺序的遍历查找要删除的节点,并在链表中删除该节点.这种思路由于需要顺序查找,时间复杂度自然就是$O(n)$了. 之所以需要从头开始查找,是因为我们需要得到将删除的节点的前面一个节点.在单向链表中,节点中没有指向前一个节点的指针,所以只好从链表的头结点开始顺序查找.那是不是一定需要得到被删除的节点的前一个节点呢?答案是否定的.我们可以很方便

[LeetCode]79. Delete Node in a Linked List删除链表节点

Write a function to delete a node (except the tail) in a singly linked list, given only access to that node. Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node with value 3, the linked list should become 1 -> 2 ->