【剑指offer❤️】18.删除链表节点

题目一:在O(1)时间删除链表结点

给定单向链表的一个节点指针,定义一个函数在O(1)时间删除该结点。

假设链表一定存在,并且该节点一定不是尾节点。

JAVA

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public void deleteNode(ListNode node) {
        ListNode p = node.next;
        
        node.val = p.val;
        node.next = p.next;
        
        p=null;
    }
}

C++

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    void deleteNode(ListNode* node) {
        auto p =node->next;
        
                
        // node->val  = p->val;
        // node->next = p->next;
        *node = *(node->next);
        
        delete p;
        
    }
};

二.删除链表中重复的节点

一个指针 p指向原来的 pHead
一个指针 pre 指向新的 newHead

class Solution {
public:
    ListNode* deleteDuplication(ListNode* head) {
        ListNode* newHead = new ListNode(-1);
        newHead->next = head;
        ListNode* pre = newHead;
        ListNode* p = head;
        ListNode* q =NULL;
        while(p && p->next){   //这里还要p 不为空
            q=p->next;
            if(p->val==q->val){
                while(q&&q->val==p->val)
                    q=q->next;
                pre->next =q;
                p=q;
            }
            else{
                pre=p;
                p=q;
            }
        }
        return newHead->next;
    }
};

只要一个指向 newHead 的指针:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* deleteDuplication(ListNode* head) {
        auto newHead = new ListNode(-1);
        newHead->next =head;
        ListNode* p = newHead;
        ListNode* q =NULL;
        while(p->next){
            q= p->next;
            while(q && q->val==p->next->val)
                q=q->next; //q跳出这个while的时候 q的值和p的值已经不等了
           //因为p指向的是newHead q才是链表的第一个数,也就算说
           //p之后的两个数不重复
            if(p->next->next==q)
                p=p->next;//q之前的一个数判断了 但是q在下一个数的第一个位置
            else  //p和q差了一个以上 说明 p之后到q之前的数是重复的 直接跳过
                p->next=q;
        }
        return newHead->next;
    }
};

在这里插入图片描述

在二的基础上改:重复出现的数也要保留下一个:

就是只有一个指针的判断

while(q&&q->val== p->val)
        q=q->next;
if(p->next!=q)  // 只有一开始走了while循环才会有p->next !=q 这时候
    p->next=q;
else
    p=q;

C++:

class Solution {
public:
    ListNode* deleteDuplication(ListNode* pHead)
    {
        ListNode* newHead = new ListNode(-1);
        newHead->next =pHead;
        ListNode* p = newHead;
        while(p->next){
            ListNode* q= p->next;
            //因为 p指向的是newHead 这个while第一个数是不去判断的
            //因为我们要是的是重复也要保留下一个,所以直接 p=q了
            //第二层循环开始 才会判断while,如果等了 
            //q是到了第一个和p不等的数
            while(q&&q->val== p->val) 
                q=q->next;
            //如果 q跳了很多次 说明p重复了 我们的p已经有一个了
            //直接就p-next=q 指向q的第一个数就行了
            if(p->next!=q)
                p->next=q;
             //如果q在p的后面 那就说明只有一个p的值 直接p=q
            else
                p=q;
        }
         return newHead->next;
    }
};

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值