【链表专题】剑指 Offer 18. 删除链表的节点

本问题对应课程链接:剑指offer刷题第二期
要求:
1、请打卡你的解题代码,如果能简单说一下思路则简单说一下思路,请代码不要直接抄袭复制我题解区给的代码哦。
2、给出你代码所用的时间复杂度和空间复杂度

第一次打卡主要:打卡的时候,代码支持 markdown 格式,并且必须要指定语言,比如

共以下 100 个回答

  • lucca 普通 2022年12月30日 上午12:41

    思路

    添加一个数据为空的头节点,这样原来的头节点删除就不用做特殊判断
    – 时间复杂度O(N)
    – 空间复杂度O(1)

    代码

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            ListNode node = new ListNode();
            node.next = head;
            head = node;
    
            for (ListNode p = head.next, pre = head; p != null; pre = p, p = p.next) {
                if (p.val == val) {
                    pre.next = p.next;
                    break;
                }
            }
            return head.next;
        }
    }
    
    0 赞同 0 条回复
  • mpweixin用户 普通 2022年11月17日 下午9:26
    class Solution:
        def deleteNode(self , head: ListNode, val: int) -> ListNode:
            # 加入一个头节点
            addhead = ListNode(0)
            addhead.next = head
            # 更新节点位置,前序节点和当前节点
            pre = addhead
            cur = head
            # 找到目标节点,断开连接,指向后一个
            # 遍历链表
            while cur is not None:
                if cur.val == val:
                    pre.next == cur.next
                    break
                pre = cur
                cur = cur.next
            return addhead.next
    
    0 赞同 0 条回复
  • PatNick 普通 2022年11月13日 上午10:07
    def deleteNode(head:ListNode,val:int)->ListNode:
        if head == None:
            return None
        if head.val == val:
            return head.next
        # 当前节点
        cur = head
        # 记录前一个节点
        before = None
        # 记录下一个节点
        # next = head.next
        while cur.next:
            # 首先向前记录before的内容,如果万一cur就是要找的值,要将before直接指向after
            before = cur
            cur = cur.next
            # next = next.next
    
            if cur.val == val:
                before.next = cur.next
                return head
    
        return head
    
    0 赞同 0 条回复
  • 杨帆 普通 2022年10月31日 下午4:39

    static class Solution {
    public ListNode deleteNode(ListNode head, int val) {
    return delNode(null,head,head,val);
    }

        public ListNode delNode(ListNode preNode,ListNode nowNode,ListNode headNode, int val){
            int value = nowNode.val;
            ListNode nextNode = nowNode.next;
            if(value == val){
                //前一个结点为null说明是头节点
                if(preNode == null){
                    return nowNode.next;
                }
                preNode.next = nextNode;
                return headNode;
            }
            else{
                if(nextNode == null){
                    return headNode;
                }
                return delNode(nowNode,nextNode,headNode,val);
            }
        }
    }
    

    时间O(n),空间O(1)

    0 赞同 0 条回复
  • 格格巫 普通 2022年10月30日 下午4:23

    下面是代码

    /**
     * Definition for singly-linked list.
     * function ListNode(val) {
     *     this.val = val;
     *     this.next = null;
     * }
     */
    /**
     * @param {ListNode} head
     * @param {number} val
     * @return {ListNode}
     */
    var deleteNode = function(head, val) {
        let per = new ListNode(-1);     //创建虚拟节点
        per.next = head;    //虚拟节点指向head
        let cur = per;
        while(cur.next){
            if(cur.next.val === val){
               cur.next = cur.next.next;//相等,指向下下一个节点;如不相等跳过cur.next
               break;
            }
            cur=cur.next;   //如不相等,则让cur指向下一个节点继续循环
        }
        return per.next
    
    };
    
    0 赞同 0 条回复
  • Mermaidᯤ⁶ᴳ 普通 2022年10月30日 上午11:48

    链表删除 复杂度O(1)

    两步走

    第一步:定位节点

    while遍历,直到head.valval时弹出

    第二步:修改引用

    当找到目标节点时,pre.next=cur.next

    特例

    当应删除头节点head时,直接返回head.next即可,这一步可以大大提升效率

    链表首先要找到前驱节点和后继节点

    创新思维:

    当我们要删除一个节点时,并不一定要删除这个节点本身,可以先把下一个节点的内容复制出来覆盖被删除的节点内容,然后把下一个节点删除即可。

    # Definition for singly-linked list.
    # class ListNode:
    #     def __init__(self, x):
    #         self.val = x
    #         self.next = None
    class Solution:
        def deleteNode(self, head: ListNode, val: int) -> ListNode:
            if head.val==val: return head.next #特例
            pre,cur=head,head.next
            #遍历链表
            while cur and cur.val!=val:
                pre,cur=cur,cur.next
            #当遍历到了cur时,让pre.next=cur.next
            if cur: pre.next=cur.next
            #返回新的链表的头节点
            return head
    
    0 赞同 0 条回复
  • 叶页耶夜烨邺 普通 2022年10月28日 下午5:57
    class Solution {
    public:
        ListNode* deleteNode(ListNode* head, int val) {
            ListNode* dummy = new ListNode(-1);
            dummy->next = head;
            ListNode* curr = dummy;
            while(curr && curr->next){
                if(curr->next->val == val){
                    curr->next = curr->next->next;
                }else{
                    curr = curr->next;
                }
            }
            return dummy->next;
        }
    };
    
    0 赞同 0 条回复
  • 糖鑫 普通 2022年10月27日 下午11:25

    代码如下

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            if(head.val==val){
                return head.next;
            }
            ListNode node;
            ListNode pre=head;
            while(pre.next!=null){
                node=pre.next;
                if(node.val==val){
                    pre.next=node.next;
                    return head;
                }
                pre=pre.next;
            }
            return head;
        }
    }
    
    0 赞同 0 条回复
  • 。。。。 普通 2022年10月27日 下午1:44

    代码如下

    class Solution {
    public:
        ListNode* deleteNode(ListNode* head, int val) {
        if (head <span class="text-highlighted-inline" style="background-color: #fffd38;"> nullptr) return nullptr;
                    if(head->val</span>val) return head->next;
                    ListNode* pre=head;
                    ListNode* cur=head->next;
                    while((cur!=nullptr)&&(cur->val!=val))
                    {
                        pre=cur;
                        cur=cur->next;
                    }
                 if(cur != nullptr) pre->next=cur->next;
        return head;
        }
    };
    

    时间o(n)空间(1)

    0 赞同 0 条回复
  • hmmm 普通 2022年10月26日 下午9:13

    下面是代码:

    c++
    

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

        ListNode *q = head;
        while(p)
        {
            if(p->val == val)
            {
                q->next = p->next;
                return head;
            }
            else {
                q = p;
                p = p->next;
            }
        }
        return head;
    }
    

    };

    0 赞同 0 条回复
  • 彭靖 永久会员 2022年10月26日 下午3:29
    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* deleteNode(ListNode* head, int val) 
        {
            ListNode* current=head;
            ListNode* temp;
            while(current!=NULL&&current->next!=NULL)
            {
                if(head->val==val)
                {
                    temp=head->next;
                    head->next=NULL;
                    head=temp;
                    current=head;
                }
                if(current->next->val==val)
                {
                    current->next=current->next->next;
                }
                current=current->next;
            }
    
    
            return head;
        }
    };
    

    跨考仔努力中

    0 赞同 0 条回复
  • 君有云兮 普通 2022年10月25日 下午8:06

    //测试Demo1

    
    public ListNode deleteNode(ListNode head,int val){
        if(head==null){
            return head;
        }
        if(head,val==val){
            return head.next;
        }
        ListNode pre=head;
        ListNode curr=head.next;
        while(curr!=null&&curr.val!=val){
            pre=vurr;
            curr=curr.next;
        }
        if(curr!=null){
            pre.next=curr.next;
        }
        return head;
    }
    
    0 赞同 0 条回复
  • mpweixin用户 普通 2022年10月25日 下午3:59

    class Solution:

    def deleteNode(self, head: ListNode, val: int) -> ListNode:

    ​ dummy = ListNode(next = head)

    ​ cur = dummy

    ​ while cur.next:

    ​ if cur.next.val val:

    ​ if not cur.next.next!=None:

    ​ cur.next = None

    ​ else:

    ​ cur.next = cur.next.next

    ​ cur = cur.next

    ​ else:

    ​ cur = cur.next

    ​ return dummy.next

    时间o(n),空间o(1)

    0 赞同 0 条回复
  • 和 普通 2022年10月25日 下午3:06
    public ListNode deleteNode(ListNode head, int val) {
            if(head==null){return head;}
            ListNode list=head;
            while (list.next != null) {
                if (list.val == val) {
                    list.val = list.next.val;
                    list.next = list.next.next;
                    return head;
                }else if(list.next.val==val&&list.next.next==null){
                    //要删除的节点为尾结点进行删除
                    list.next=null;
                    return head;
                }else {
                    list = list.next;
                }
            }
            return head;
        }
    
    0 赞同 0 条回复
  • 星河 普通 2022年10月24日 下午9:27
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            if(head.val == val) return head.next;
            ListNode pre = head, cur = head.next;
            while(cur != null && cur.val != val) {
                pre = cur;
                cur = cur.next;
            }
            if(cur != null) pre.next = cur.next;
            return head;
        }
    }
    时间O(N),空间O(1)
    
    0 赞同 0 条回复
  • XR 普通 2022年10月24日 下午7:01

    删除空结点思路:
    找到结点位置,将结点前一个结点的地址部分指向下一个结点即可完成删除
    注意头结点判断与尾结点为空。

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     struct ListNode *next;
     * };
     */
    
    struct ListNode* deleteNode(struct ListNode* head, int val){
        struct ListNode* cur = head;
        if(head->val == val){
            return head->next;
        }
        while((cur->next->val != val) && (cur->next != NULL)){
            cur = cur->next;
        }
        if(cur->next != NULL){
            cur->next = cur->next->next;
        }
        return head;
    }
    
    0 赞同 0 条回复
  • 🚲南下 普通 2022年10月24日 上午9:42

    复杂度:
    时间复杂度为O(n),空间复杂度O(1)

    class Solution {
    public:
        ListNode* deleteNode(ListNode* head, int val) {
            if(head->val == val){
                return head->next;
            }
            ListNode* pre = head; //定义父节点
            ListNode* cur = head->next; //要删除的当前节点
            while(cur->val!=val && cur->next!=nullptr){
                pre = cur;
                cur = cur->next;
            }
            if(cur!=nullptr){
                pre->next = cur->next; //改变pred的指向
            }
            return head; 
    
        }
    };
    
    0 赞同 0 条回复
  • 啊哈 普通 2022年10月24日 上午12:03
    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* reverseList(ListNode* head) {
    
            ListNode* cur = head;
            ListNode* tail = NULL;
    
            while(cur != NULL)
            {
                ListNode* temp = cur->next;     //节点记录原链表的cur下一个节点地址
                cur->next = tail;   //使得cur当前next指向tail;
                tail = cur;     //tial 移到cur位置
                cur = temp;     //cur回到原链表的下一个位置
            }
            return tail;
        }
    };
    
    

    时间复杂度O(n)
    空间复杂度O(1)

    0 赞同 0 条回复
  • 理论分析者 普通 2022年10月23日 下午8:38

    class Solution {
    public ListNode deleteNode(ListNode head, int val) {
    //定义一个虚拟节点
    ListNode res=head;
    //判断头节点
    if(head.val val) return head.next;
    //判断后面的节点
    while(head!=null){
    if(head.next.val
    val){
    head.next=head.next.next;
    return res;
    }
    head=head.next;
    }
    return res;
    }
    }

    0 赞同 0 条回复
  • cxc 普通 2022年10月23日 下午8:05
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            if(head == null) return null;
    
            ListNode h = head;
            //定义一个dummy节点
            ListNode dummy = new ListNode(0);
            dummy.next = head;
    
            if(head.val == val) {
                return head.next;
            }
    
            while(h.val != val) {
                dummy = h;
                h = h.next;
            }
    
            dummy.next = h.next;
            return head;
        }
    
    }
    
    0 赞同 0 条回复
  • Stoician 普通 2022年10月23日 下午8:03

    “`打卡C++
    /**
    * Definition for singly-linked list.
    * struct ListNode {
    * int val;
    * ListNode *next;
    * ListNode(int x) : val(x), next(NULL) {}
    * };
    */
    class Solution {
    public:
    ListNode* deleteNode(ListNode* head, int val) {
    ListNode* dummyHead = new ListNode(0);
    dummyHead->next = head;
    ListNode* cur = dummyHead;
    while(cur->next != NULL){
    if(cur->next->val == val){

                cur->next = cur->next->next;
    
           }else{
               cur = cur->next;
           }
        }
        head = dummyHead->next;
        return head;
    
    }
    

    };

    “`

    0 赞同 0 条回复
  • Ruby🗽 普通 2022年10月23日 下午5:16
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            if( head == null )
                return head;
            if( head.val == val )
                return head.next;
            ListNode temp = head.next;
            ListNode pre = head;
            while( temp!=null ){
                if( temp.val == val ){
                    pre.next = temp.next;
                    return head;
                }
                temp = temp.next;
                pre = pre.next;
            }
            return head;
        }
    }
    

    时间复杂度 n
    空间复杂度 1

    0 赞同 0 条回复
  • just 普通 2022年10月23日 下午4:10

    “`c++

    class Solution {

    public:

    ListNode* deleteNode(ListNode* head, int val) {
    
        ListNode* dummy=new ListNode(0,head);//虚拟节点
    
        ListNode* cur=dummy;
    
        while(cur->next){
    
            if(cur->next->val==val){
    
                cur->next=cur->next->next;
    
            }
    
            else cur=cur->next;
    
        }
    
        head=dummy->next;
    
        delete dummy;
    
        return head;
    
    }
    

    };

    0 赞同 0 条回复
  • Gg 普通 2022年10月23日 下午4:09
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            // 定义虚拟头节点
            ListNode dummy = new ListNode();
            dummy.next = head;
            // 定义遍历链表的指针
            ListNode curr = dummy;
            // 遍历链表
            while(curr != null && curr.next != null){
                // 指针的下一个节点等于目标值,进行删除
                if(curr.next.val == val){
                    curr.next = curr.next.next;
                }
                curr = curr.next;
            }
            return dummy.next;
        }
    }
    
    0 赞同 0 条回复
  • Xiao 普通 2022年10月23日 下午2:04
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            ListNode pnext=head.next;
            ListNode p=head;
           //第一种情况
            if(head==null){
                return head;
            }
           //第二种情况
            if(head.val==val){
                return head.next;
            }
           //遍历链表,寻找要删掉的节点
            while(pnext!=null){
                if(pnext.val==val){
                    p.next=pnext.next;
                    return head;
                }
                p=pnext;
                pnext=pnext.next;
            }
            return head;
        }
    }
    

    时间复杂度:O(n)
    空间复杂度:O(1)

    0 赞同 0 条回复
  • 云雾里 普通 2022年10月23日 上午11:23
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            //当前链表为空,返回head
            if(head==null){
                return head;
            }
            //头节点等于目标值,返回 head.next
            if(head.val==val){
                return head.next;
            }
            //指针temp
            ListNode temp = head;
            //从head的next开始,使用当前链表的next,可以单指针实现,无需双指针
            while(temp.next!=null){
                //当前节点的next的值和目标值一样,表明需要删除当前节点的next
                //当前节点next指向当前节点next.next
                if(temp.next.val==val){
                    temp.next=temp.next.next;
                    break;
                }
                //指针下移
                temp=temp.next;
            }
            return head;
        }
    }
    
    0 赞同 0 条回复
  • 白给小王子 普通 2022年10月23日 上午8:41

    “`java

    //leetcode submit region begin(Prohibit modification and deletion)
    /**
    * Definition for singly-linked list.
    * public class ListNode {
    * int val;
    * ListNode next;
    * ListNode(int x) { val = x; }
    * }
    */
    class Solution {
    public ListNode deleteNode(ListNode head, int val) {
    ListNode temp = head;
    while (temp.next != null) {
    ListNode aha = temp;
    temp = temp.next;
    if(temp.val val){
    aha.next = temp.next;
    }else if(head.val
    val){
    head = head.next;
    }
    }
    return head;
    }
    }
    //leetcode submit region end(Prohibit modification and deletion)
    执行耗时:0 ms,击败了100.00% 的Java用户
    内存消耗:41.3 MB,击败了5.94% 的Java用户

    0 赞同 0 条回复
  • 浅夏的无奈 普通 2022年10月23日 上午1:00
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            //定义一个虚拟节点
            ListNode res=head;
            //判断头节点
            if(head.val == val) return head.next;
            //判断后面的节点
            while(head!=null){
                if(head.next.val ==val){
                    head.next=head.next.next;
                    return res;
                }
                head=head.next;
            }
            return res;
        }
    }
    
    0 赞同 0 条回复
  • mpweixin用户 永久会员 2022年10月22日 下午11:30
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            if(head==null)
                return head;
            if(head.val == val)    
                return head.next;
            ListNode temp=head.next;
            ListNode pre=head;
            while(temp!=null){
                if(temp.val==val){
                     pre.next=temp.next;
                     return head;
                }
                temp = temp.next;
                pre = pre.next;     
            }
            return head;
        }
    }
    
    0 赞同 0 条回复
  • Tolkien 永久会员 2022年10月22日 下午10:31

    双指针
    1. 时间复杂度:O(n)
    2. 空间复杂度:O(1)
    3. 代码

    public ListNode deleteNode2(ListNode head, int val) {
            ListNode dummyHead = new ListNode(-1);
            dummyHead.next = head;
    
            // 1. 如果链表为空,则返回空
            // 2. 如果删除的节点为头节点,则返回头结点之后的链表
            // 因为有虚拟头节点,因此第一二步省略
    
            // 3. 遍历链表,直到当前节点为空,若当前结点值与删除的节点值相同,则进行删除操作并返回链表
            ListNode prev = dummyHead;
            ListNode curr = prev.next;
    
            while (curr != null) {
                if (curr.val == val) {
                    prev.next = curr.next;
                    return dummyHead.next;
                }
                prev = curr;
                curr = curr.next;
            }
    
            return dummyHead.next;
    
    0 赞同 0 条回复
  • -辰华- 永久会员 2022年10月22日 下午9:16

    使用的是单指针
    (1)当要删除的节点为头节点head时,返回头节点的下一节点head.next;
    (2)初始化cur;
    (3)循环遍历,直到找到要删除的节点则结束;
    (4)删除节点:cur的next指向待删除节点的下一节点(即:cur的下下一节点)cur.next.next;
    (5)返回头节点head。

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            if(head == null) return null;
            if(head.val == val) return head.next;
            ListNode cur = head;
            while(cur.next != null && cur.next.val != val) {
                cur = cur.next;
            }
            if(cur.next != null) cur.next = cur.next.next;
            return head;
        }
    }
    

    时间复杂度:O(n)
    空间复杂度:O(1)

    0 赞同 0 条回复
  • 波波_1936 普通 2022年10月22日 下午9:09
     public static ListNode deleteNode(ListNode head, int val) {
            if (head == null) return head;
            ListNode node = new ListNode(-1);
            node.next = head;
            ListNode res = node;
            while (node.next != null) {
                if (node.next.val == val) {
                    node.next = node.next.next;
                } else {
                    node = node.next;
                }
            }
            return res.next;
        }
    
    

    时间复杂度 O(N)
    空间复杂度O(1)

    0 赞同 0 条回复
  • 云 永久会员 2022年10月22日 下午8:22

    首先要找到删除的这个元素
    删除一个数之前要找到他的前一个结点,然后把他的next直接指向next.next

    import java.util.*;
    
    /*
     * public class ListNode {
     *   int val;
     *   ListNode next = null;
     *   public ListNode(int val) {
     *     this.val = val;
     *   }
     * }
     */
    
    public class Solution {
        /**
         * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
         *
         * 
         * @param head ListNode类 
         * @param val int整型 
         * @return ListNode类
         */
        public ListNode deleteNode (ListNode head, int val) {
            // write code here
            ListNode dummyHead=new ListNode(-1);
            dummyHead.next=head;
            ListNode node=dummyHead;
            while(node.next!=null){
                if(node.next.val==val){
                    node.next=node.next.next;
                    break;
                }
                node=node.next;
            }
            return dummyHead.next;
    
    
        }
    }
    

    时间复杂度:O(n)

    0 赞同 0 条回复
  • Monster Dump 普通 2022年10月22日 下午8:17
    • 代码实现 (Java)
        public ListNode deleteNode(ListNode head, int val) {
            if (head == null) {
                return head;
            }
            if (head.val == val) {
                return head.next;
            }
            ListNode pre = head;
            ListNode curr = head.next;
            while (curr != null && curr.val != val) {
                pre = curr;
                curr = curr.next;
            }
            if (curr != null) {
                pre.next = curr.next;
            }
            return head;
        }
    
    • 时间复杂度: O(n)
    • 空间复杂度: O(1)
    0 赞同 0 条回复
  • Magi 普通 2022年10月22日 下午8:10
    //先判断头节点为空的情况
            if (head == null) {
                return null;
            }
    
            //判断只有一个头节点的情况
            if (head.val == val) {
                return head.next;
            }
    
            //定义两个指针,A指针永远在B指针后面
            //a指针是辅助指针
            ListNode a = head.next;
            ListNode b = head;
    
            while (a != null) {
                //如果删除的是后面的指针所指向的节点,那么就顺位把前面的指针后移一位就可以返回整个链表
                if(a.val == val)
                {
                    b.next = a.next;
                    return head;
                }
                //如果删除的不是后面的指针所指向的节点,直到删除的值和a指针所指结点的值相等,
    
                a = a.next;
                b = b.next;
            }
            return head;
        }
    

    这道题同样是运用双指针

    0 赞同 0 条回复
  • 阿白 普通 2022年10月22日 下午7:02

    时间复杂度θ(n),空间复杂度θ(1)

    typedef struct ListNode
    {
        ListNode *next;
        int val;
    
    };
    
    ListNode *deleteNode(ListNode *head, int val)
    {
        if (head == nullptr)
            return nullptr;
        if (head->val == val)
            return head;
        ListNode *ptr = head->next;
        ListNode *temp;
        while (ptr->val != val && ptr!=nullptr)
        {
            temp = ptr;
            ptr = temp->next;
        }
        if (ptr->val == val)
        {
            temp->next = ptr->next; 
        }
    
        return head;
    }
    
    0 赞同 0 条回复
  • 韩杰 普通 2022年10月22日 下午6:53

    1,找到匹配的值,将前一个节点的next指向下一个节点
    2,时间复杂度O(n)
    空间复杂度O(n)

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            if(head==null){
                return null;
            }
            if (head.val == val){
                return head.next;
            }
    
            ListNode temp = head.next;
            ListNode pre =head;
    
            while(temp !=null){
                if (temp.val==val){
                    pre.next = temp.next;
                    return head;
                }
                temp = temp.next;
                pre = pre.next;
            }
            return head;
    }}
    
    
    0 赞同 0 条回复
  • yanshuojune 普通 2022年10月22日 下午6:47

    时间复杂度:O(n)
    空间复杂度:O(1)

    class Solution:
        def deleteNode(self, head: ListNode, val: int) -> ListNode:
            #双指针
            prev = None
            curr = head
            while curr != None:
                if curr.val == val:
                    #若要删除的节点是头节点,则将头节点指向None
                    if prev == None:
                        head = curr.next
                        break
                    #若要删除的节点是非头节点,将pre节点指向当前节点的next节点
                    prev.next = curr.next
                    break
                # 未找到对应val,则继续遍历链表中的节点
                prev = curr
                curr = curr.next
            return head
    
    0 赞同 0 条回复
  • 绍熙 普通 2022年10月22日 下午6:28

    思路:双指针,指向前一个节点,以及当前节点,注意判断边界值,以及初始化值的处理。

    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            // 如果头节点就是要删除的节点,则返回头节点的下一个节点
            if (head.val == val) {
                return head.next;
            }
            // 双指针,初始化
            ListNode pre = head, cur = head.next;
            while (cur != null && cur.val != val) {
                pre = cur;
                cur = cur.next;
            }
            if (cur != null) {
                pre.next = cur.next;
            }
            return head;
        }
    }
    
    1 赞同 0 条回复
  • 泡芙 永久会员 2022年10月22日 下午5:48

    解法:迭代
    思路:删除链表的节点其实就是找到要删除节点的位置,让上一个节点的next指针指向next.next指针即下下个节点
    特例:删除的节点是头节点or尾节点

    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            if(head == null) {
                return null;
            }
    
            if(head.val == val) {
                return head.next;
            }
    
            ListNode cur = head;
            while(cur.next != null) {
                if(cur.next.val == val) {
                    cur.next = cur.next.next;
                    return head;
                }
                cur = cur.next;
            }
            return head;
        }
    }
    

    时间复杂度:O(n),n为链表长度,while循环的删除操作为n/2次,最差为n次
    空间复杂度:O(1)

    1 赞同 0 条回复
  •   普通 2022年10月22日 下午5:16
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            // 如果链表为空
            if(head == null) return null;
            // 如果头节点数据是要删除的
            if(head.val == val) return head.next;
            ListNode ln = head;
            while(ln.next != null) {
                // 如果下一个节点的值是要删除的
                if(ln.next.val == val) {
                    ln.next = ln.next.next;
                    break;
                }
                ln = ln.next;
            }
            return head;
        }
    }
    

    时间复杂度O(n)

    0 赞同 0 条回复
  • 酥合 普通 2022年10月22日 下午4:58
    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
    
            if(null == head ) {
                return null;
            }
    
            if(head.val == val) {
                return head.next;
            }
            ListNode p = head;
            while(p.next != null) {
                if(p.next.val == val) {
                    p.next = p.next.next;
                    return head;
                }
                p = p.next;
            }
    
            return head;
    
        }
    }
    

    时间复杂度:O(n)
    空间复杂度:O(1)

    0 赞同 0 条回复
  • cxxz 普通 2022年10月22日 下午3:50

    不太会算时间空间复杂度,先去学一下~
    比较笨拙的方法,先用一个指针保存一下head->next 以便判断是否删除的是头节点。用虚拟节点遍历链表并解链要删除的节点。

    ListNode* deleteNode(ListNode* head, int val) {
            if (head == nullptr || head->next == nullptr)
                return head;
    
            ListNode* vhead = new ListNode(1);
            ListNode* head_next = head->next;
            vhead->next = head;
            while (vhead->next != NULL)
            {
                int nodeval = vhead->next->val;
                if (nodeval == val)
                {
                    vhead->next = vhead->next->next;
                    break;
                }
                vhead = vhead->next;
            }
            if (vhead->next == head_next)
                return head->next;
            return head;
        }
    
    0 赞同 0 条回复
  • Y7n05h 普通 2022年10月22日 下午3:49
    class Solution {
    public:
        ListNode *deleteNode(ListNode *head, int val) {
            ListNode t(0);
            t.next = head;
            auto *cur = &t;
            while (cur->next) {
                auto *tmp = cur->next;
                if (tmp->val == val) {
                    cur->next = tmp->next;
                    return t.next;
                }
                cur = tmp;
            }
            return t.next;
        }
    }
    

    时间复杂度:O(n)
    空间复杂度:O(1)

    0 赞同 0 条回复
  • 晨渊 普通 2022年10月22日 下午3:20
    class Solution {
    public:
        ListNode* deleteNode(ListNode* head, int val) {
            if(head == NULL){  //如果为空
                return head;  
            }
            if(head->val == val ) {//如果只有一个头指针
                return head->next;
            }
             //找到删除点
             ListNode *temp,*pre;
             temp = head->next;
             pre = head;
             while(temp->val!= val){
                  pre = temp;
                 temp=temp->next;
             }
             if(temp==NULL) return head; //没有找到
    
             //删除节点
             pre->next = temp->next;
             return head;
    
        }
    };
    

    时间复杂度O(n)
    空间复杂度O(1)

    0 赞同 0 条回复
  • cute. 普通 2022年10月22日 下午3:19

    方法:双指针

    var deleteNode = function(head, val) {
        // 初始化哨兵节点(dummy),并指向head
        let dummy = new ListNode(0, head);
        let pre = dummy;
        // cur = dummy.next = head;
        let cur = head;
        while( cur !== null) {
            if(cur.val === val) {
                pre.next = cur.next;
                break;
            }
            pre = cur;
            cur = cur.next;
        }
        return dummy.next;
    };
    

    复杂度分析:
    ● 时间复杂度: O(n)
    ● 空间复杂度: O(1)

    0 赞同 0 条回复
  • 晨 普通 2022年10月22日 下午2:29
    class Solution(object):
            # 节点为空,返回null
            if not head:
                return null
            #  如果节点为目标节点,则返回head.next
            if head.val == val:
                return head.next
            #初始化
            pre = head
            cur =  head.next
            while cur:
                if cur.val == val:
                    #删除节点
                    pre.next = cur.next
                    return head
                #遍历节点
                pre = cur
                cur = cur.next
            return head
    
    
    0 赞同 0 条回复
  • 追 普通 2022年10月22日 下午2:12
    class Solution {
    public:
        ListNode* deleteNode(ListNode* head, int val) {
            if(head->val == val) return head->next;
            ListNode *pre = head, *cru = head->next;
            while(cru != nullptr && cru->val != val){
                pre = cru;
                cru = cru->next;
            }
            if(cru != nullptr) pre->next = cru->next;
            return head;
        }
    };
    

    注意:当头节点是所需要删除的节点的特殊情况

    0 赞同 0 条回复
  • 小肸 永久会员 2022年10月22日 下午1:26

    思路:找到要删除节点target的前一个节点pre,让pre的指针域指向target的下一个节点,再把target的指针域设为空,让节点target从链表中脱离出来,方便Java虚拟机回收,对于OJ来说,程序指向完后会自动销毁内存,所以让target的指针域指向空这一步可以不做。因为头节点没有前一个节点,所以需要特殊处理,可以使用虚拟头节点让头节点也有前一个节点,也可以使用递归实现,实现的思路都是一样的。
    leetcode中测试用例中好像只有一个要删除的节点,我给出两个版本,一个是删除第一次出现的删除节点,另一个是删除所有要删除的节点,作为递归练习。

    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            return deleteNodeCore(head, val, false);
        }
        private ListNode deleteNodeCore(ListNode head, int val, boolean flag) {
            // 当前节点是null,直接返回
            if (head == null || flag == true) {
                return head;
            }
            if (head.val == val) {
                head.next = deleteNodeCore(head.next, val, true);
                return head.next;
            } else {
                head.next = deleteNodeCore(head.next, val, false);
                return head;
            }
        }
    }
    
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            // 当前节点是null,直接返回
            if (head == null) {
                return head;
            }
            // 当前节点的指针域指向子链表中已删除所以目标节点的头节点
            head.next = deleteNode(head.next, val);
            // 当前节点是要删除的节点,返回下一个节点,否则返回当前节点
            return head.val != val ? head : head.next;
        }
    }
    

    递归实现的时间和空间复杂度都为O(n)

    0 赞同 0 条回复
  • 虾仁猪心 普通 2022年10月22日 上午11:50

    思路:

    step 1:首先我们加入一个虚拟头部节点(dummyHead),并让这个虚拟头节点指向链表的头节点,这样做是因为有可能要删除的元素是链表的头节点。
    step 2:准备两个指针遍历链表,一个指针(cur)指向当前要遍历的元素,另一个指针(pre)指向该元素的前序节点,便于获取它的指针。
    step 3:遍历链表,找到目标节点,则断开连接,指向后一个。
    step 4:返回虚拟头节点的下一个节点(即是删除原素后链表的头节点)。

    public class Solution {
        /**
         * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
         *
         *
         * @param head ListNode类
         * @param val int整型
         * @return ListNode类
         */
        public ListNode deleteNode (ListNode head, int val) {
            // write code here
            if (head == null) {
                return null;
            }
            ListNode dummy = new ListNode(Integer.MIN_VALUE);
            dummy.next = head;
            ListNode cur = head;
            ListNode pre = dummy;
            while (cur != null) {
                if (cur.val == val) {
                    pre.next = cur.next;
                    break;
                }
                pre = cur;
                cur = cur.next;
            }
            return dummy.next;
        }
    }
    
    
    0 赞同 0 条回复
  • 潜行1 我是火车王! 普通 2022年10月22日 上午11:49

    涉及结点的增删注意头结点 -> 添加虚拟头结点进行统一处理:

    // 用虚拟头结点
    func deleteNode(head *ListNode, val int) *ListNode {
        if head == nil {
            return head
        }
    
        YourHead := &ListNode{
            Next: head,
        }
    
        curNode := head
        preNode := YourHead
    
        for curNode != nil {
            if curNode.Val == val {
                preNode.Next = curNode.Next
                return YourHead.Next
            }
            preNode, curNode = curNode, curNode.Next
        }
    
        return YourHead.Next
    }
    
    
    0 赞同 0 条回复
  • YZ 普通 2022年10月22日 上午11:43
    class Solution {
    public:
        ListNode* deleteNode(ListNode* head, int val) {
            if(head==NULL)   //判断链表是否为空
            {
                return NULL;
            }
            if(head->val==val)  //判断要删除的结点是否是头结点
            {
                return head->next;
            }
            ListNode *pre = head;   //创建一个指针指向被删除点的前一个结点
            ListNode *sce = pre->next;  //创建另一个指针指向被删除点
            while(sce!=NULL)
            {
                if(sce->val==val)
                {
                    pre->next = sce->next;
                    return head;
                }
                pre = pre->next;
                sce = sce->next;
            }
            return head;
        }
    };
    

    解题思路
    1.在链表中删除一个结点需要它和它之前的结点,可以设置一个指针或两个指针
    2.设置两个指针,一个sce指向删除节点的自身,另一个指向被删除节点之前的结点
    3.利用pre->next = sce->next;删除结点
    一定记得判断被删除结点是否为头结点和判断链表是否为空
    时间复杂度O(n)
    空间复杂度O(1)

    0 赞同 0 条回复
  • 优秀市民 普通 2022年10月22日 上午11:36
    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            if (head.val == val){
                return head.next;
            }
            ListNode pre = head;
            ListNode cur = head.next;
            while(cur != null && cur.val !=val){
                pre = cur;
                cur = cur.next;
            }
            if (cur!=null){
                pre.next = cur.next;
            }
            return head;
    
    
        }
    }
    

    时间复杂度O(N)
    空间复杂度O(1)

    0 赞同 0 条回复
  • 刺猬 普通 2022年10月22日 上午11:20
    class Solution {
    public:
        ListNode* deleteNode(ListNode* head, int val) {
            if(head == nullptr)
                return nullptr;
            if(head->val == val)
                return head->next;
            ListNode* pre = head;
            ListNode* cur = head->next;
            while(cur->next != nullptr && cur->val !=val)
            {
                pre = cur;
                cur = cur->next;
            }
            pre->next = cur->next;
            return head;
        }
    };
    

    时间复杂度O(N)
    空间复杂度O(1)

    0 赞同 0 条回复
  • 小趴菜 永久会员 2022年10月22日 上午10:50

    class Solution {
    public ListNode deleteNode(ListNode head, int val) {
    //判断一下如果头部为查找节点返回其下个节点的地址
    if(head.valval){
    return head.next;
    }
    //创建双指针一个指向头部一个指向下一个地址即初始化双指针
    ListNode pre = head;
    ListNode cur = head.next;
    //遍历查找直到找到该节点时跳出
    while(cur.val!=val&&cur.next!=null){
    pre=cur;
    cur=cur.next;
    }
    //实现删除操作
    if(cur!=null){
    pre.next=cur.next;
    }
    return head;

    }
    

    }

    0 赞同 0 条回复
  • 你有点可爱喔 普通 2022年10月22日 上午10:44

    解题思路:
    1.双指针。初始化双指针
    2.需要对下一个节点判断,是否为空
    时间复杂度O(n);长度为
    空间复杂度O(1)

    public ListNode deleteNode(ListNode head, int val) {
       ListNode pre = null; //前驱节点
       ListNode cur = head; 
        while(cur!=null) {
          //找到待删除的节点
            if(cur.val == val){
                //下一个节点为空的时候
                if(pre==null){
                    return cur.next;
                }
                pre.next = cur.next;
                return head;
            }
            pre = cur;
            cur = cur.next;
        }
        return null;
    
    }
    
    0 赞同 0 条回复
  • 派大星 普通 2022年10月22日 上午9:29
    //使用双指针,进行遍历删除
    //时间复杂度:O(n)
    //空间复杂度:O(1)
    public class Solution {
    
        public ListNode deleteNode(ListNode head, int v) {
            if (head != null) {
                ListNode currentNode = head.next;
                ListNode preNode = head;
                if (head.val == v) {
                    return head.next;
                }
                while (currentNode != null) {
                    if (currentNode.val == v) {
                        preNode.next = currentNode.next;
                        return head;
                    } else {
                        preNode = currentNode;
                        currentNode = currentNode.next;
                    }
                }
    
            } else {
                return null;
            }
            return head;
        }
    }
    
    
    0 赞同 0 条回复
  • 是梦终空 永久会员 2022年10月22日 上午9:12

    先判断特殊情况,然后单指针遍历,让val所在节点的上一个节点指向val的next节点
    时间复杂度:O(n)
    空间复杂度:O(1)

    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            if(head == null)    return null;
            if(head.val == val) return head.next;
            ListNode list = head;
            while(list.next!=null){
                if(list.next.val == val){
                    break;
                }
                list = list.next;
            }
            if(list.next!=null)
                list.next = list.next.next;
            return head;
        }
    }
    
    0 赞同 0 条回复
  • 单个酒窝儿 普通 2022年10月22日 上午8:52

    1、先考虑特殊情况,将头节点为空和头节点为要删除节点的情况做一个返回
    2、定义双指针(pre cur)分别指向前两个节点,当第二个指针不为NULL时,就每次向后移动一步
    3、每次判断cur的值是否等于val,如果等于就将前一个节点的指向本节点的后一个节点。如果不等于val,那么双指针同时后移一步

    <

    pre>class Solution {
    public:
    ListNode* deleteNode(ListNode* head, int val) {
    if(head NULL) return NULL;
    if(head->val
    val) return head->next;

    <

    pre> ListNode* cur = head->next;
    ListNode* pre = head;
    while(cur != NULL){
    if(cur->val val){
    pre->next = cur->next;
    return head;
    }
    cur = cur->next;
    pre = pre->next;
    }
    return head;
    }
    };

    1 赞同 0 条回复
  • 乱世枭雄 普通 2022年10月22日 上午8:41

    先考虑特殊情况:空链表、头指针的值即为删除值
    排除特殊后定义当前节点以及当前节点前一个节点,遍历链表,删除

    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            if(head.val==val){
                return head.next;
            }
            if(head==null){
                return null;
            }
    
            ListNode temp=head.next;
            ListNode pre=head;
            while(temp != null){
                if(temp.val==val){
                    pre.next=temp.next;
                    return head;
                }
                temp=temp.next;
                pre=pre.next;
    
            }
            return head;
        }
    }
    
    0 赞同 0 条回复
  • 努力刷题 普通 2022年10月22日 上午3:58

    双指针

    class Solution(object):
        def deleteNode(self, head, val):
            """
            :type head: ListNode
            :type val: int
            :rtype: ListNode
            """
            if not head:
                return None
            if head.val == val:
                return head.next
            tmp = head.next
            p = head
            while tmp:
                if tmp.val == val:
                    p.next = tmp.next
                tmp = tmp.next
                p = p.next
            return head
    
    0 赞同 0 条回复
  • 黎昕 普通 2022年10月22日 上午1:30

    单指针遍历

    class Solution {
    public:
        ListNode* deleteNode(ListNode* head, int val) {
            if(head==NULL)return NULL;
    
    
    <pre><code>    if(head->val==val){
            head=head->next;
            return head;
        }
    
        ListNode* p1=head;
        ListNode* p2=head->next;
        while(p2!=NULL){
            if(p2->val==val){
                p1->next=p2->next;
                break;
            }
            p1=p2;
            p2=p2->next;
        }
        return head;
    
    }
    </code></pre>
    
    };
    
    
    0 赞同 0 条回复
  • 訁訁訁訁訁 普通 2022年10月22日 上午12:25

    时间复杂度O(1) 空间复杂度O(1)

    双指针

    //自己实现,略显臃肿
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            ListNode cur = head;
            ListNode pre = null;
            while(cur != null){
                if(cur.val == val && pre == null){
                    return cur.next;
                }else if(cur.val == val && pre != null){
                    pre.next = pre.next.next;
                    return head;
                }else{
                    pre = cur;
                    cur = cur.next;
                }
            }
            return head;
        }
    }
    
    //优化
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            if(head == null) return null;
            if(head.val == val) return head.next;
            ListNode cur = head.next;
            ListNode pre = head;
            while(cur != null){
                if(cur.val == val){
                    pre.next = cur.next;
                    return head;
                }
                pre = cur;
                cur = cur.next;
            }
            return head;
        }
    }
    

    递归

    //递归
    //时间复杂度O(n)空间复杂度O(n)系统栈
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            if(head == null) return null;
            if(head.val == val) return head.next;
            head.next = deleteNode(head.next,val);
            return head;
        }
    }
    

    虚拟头节点

    //使用虚拟头节点
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            ListNode dummy = new ListNode(-1);
            dummy.next = head;
            ListNode cur = dummy;
            while(cur.next != null){
                if(cur.next.val == val){
                    //删除节点
                    cur.next = cur.next.next;
                    return dummy.next;
                }
                cur = cur.next;
            }
            return dummy.next;
        }
    }
    
    0 赞同 0 条回复
  • lone。 普通 2022年10月21日 下午11:53
    • 解法一 :双指针
      class Solution1 {
        public ListNode deleteNode(ListNode head, int val) {
            //如果链表为空直接返回
            if (head == null) {
                return null;
            }
      
            //如果要删除的节点是头结点,返回链表的下一节点
            if (head.val == val) {
                return head.next;
            }
      
            //cur作为遍历的当前节点,pre作为上一节点
            ListNode cur = head.next;
            ListNode pre = head;
      
            while (cur != null) {
                if (cur.val == val) {
                    //当前节点即是要删除节点,将上一节点pre的next改为当前节点cur的下一节点
                    pre.next = cur.next;
                    break;
                }
                //节点向下遍历替换
                cur = cur.next;
                pre = pre.next;
            }
      
            return head;
        }
      
      

      时间复杂度:O(N)

      空间复杂度:O(1)

    • 解法二:递归

      class Solution2 {
        public ListNode deleteNode(ListNode head, int val) {
      
            //如果链表为空直接返回
            if (head == null) {
                return null;
            }
      
            //如果要删除的节点是头结点,返回链表的下一节点
            if (head.val == val) {
                return head.next;
            }
      
            head.next = deleteNode(head.next, val);
            return head;
        }
      }
      

      时间复杂度:O(N)

      空间复杂度:O(N)

    • 解法三:虚拟头节点

      解法一和解法二删除头节点和删除非头节点 代码相似。

      定义一个虚拟头节点,避免将头节点单独逻辑判断,返回虚拟节点的下一节点

      class Solution3 {
        public ListNode deleteNode(ListNode head, int val) {
      
            ListNode dummy = new ListNode(-1);
            dummy.next = head;
      
            ListNode cur = dummy;
      
            while (cur.next != null) {
                if (cur.next.val == val) {
                    //当前节点即是要删除节点,将上一节点pre的next改为当前节点cur的下一节点
                    cur.next = cur.next.next;
                    break;
                }
                //节点向下遍历替换
                cur = cur.next;
            }
      
            return dummy.next;
        }
      }
      

      时间复杂度:O(N)

      空间复杂度:O(1)

    0 赞同 0 条回复
  • 溴麝香草酚蓝 普通 2022年10月21日 下午11:53
    • 思路

      直接遍历

      1. 遍历链表,同时将节点值与目标值val进行比较,相同就删除节点。
      2. 使用curNode进行遍历,使用lastNode记录节点的上一节点,删除节点时,先将lastNode.next指向curNode.next,再将null赋值给curNode,结束遍历。
      3. 遍历前先判断输入头节点(head)是否为null,是则直接返回null,否则判断头节点的值是否与val相等,相等则直接返回head.next,不相等则开始遍历。
    • 代码

    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            if (head == null) {
                return null;
            }
            if (head.val == val) {
                return head.next;
            }
            ListNode curNode = head;
            ListNode lastNode = head;
            while (curNode != null) {
                if (curNode.val == val) {
                    lastNode.next = curNode.next;
                    curNode = null;
                } else {
                    lastNode = curNode;
                    curNode = curNode.next;
                }
            }
            return head;
        }
    }
    
    • 时间复杂度:O(n)

    • 空间复杂度:O(1)

    0 赞同 0 条回复
  • mpweixin用户 普通 2022年10月21日 下午11:51
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            // 判断删除的第一个元素是不是头节点
            if(head.val==val){
                return head.next;
            }
            ListNode pre = head;
            ListNode curr = head.next;
            while(curr!=null){
                //找到删除节点的前一个节点
                if(curr.val==val){
                  pre.next=curr.next;
                    break;   
                }
                pre=pre.next;
                curr=curr.next;
            }
            return head;
        }
    }
    
    0 赞同 0 条回复
  • Spermalow 普通 2022年10月21日 下午11:42
    class Solution {
    public:
        ListNode* deleteNode(ListNode* head, int val) {
            if (!head) return head;    
            if (head->val == val) return head->next;    // 如果删除的值为头结点,直接返回头节点下一个结点即可
            ListNode * currentNode = head;
            ListNode * nextNode = head->next;
            while (nextNode) {    // 由于head头结点已经在前面判断过了,所以直接从下一个点进行遍历
                if (nextNode->val == val) {    // 如果该点值与目标值一致,则使用该点的上一个结点进行“跳跃式指向”即可完成删除(可以画图理解)
                    currentNode->next = currentNode->next->next;
                }
                // 两个指针都需要往后走一步
                currentNode = currentNode->next;
                nextNode = nextNode->next;
            }
            return head;
        }
    };
    

    时间O(n), 空间O(1)

    0 赞同 0 条回复
  • Error 普通 2022年10月21日 下午11:36
    class Solution:
        def deleteNode(self, head: ListNode, val: int) -> ListNode:
            if not head:
                return None
            if head.val == val:
                return head.next
    
            cur = head
            while cur.next:
                if cur.next.val == val:
                    cur.next = cur.next.next
                    break
                cur = cur.next
    
            return head
    

    时间复杂度 O(n)

    0 赞同 0 条回复
  • 易水寒 永久会员 2022年10月21日 下午10:40
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            ListNode dummy = new ListNode(-1);
            dummy.next = head;
            ListNode cur = dummy;
            while(cur.next != null) {
                if(cur.next.val == val) {
                    cur.next = cur.next.next;
                    break;
                }
                cur = cur.next;
            }
            return dummy.next;
        }
    }
    //复杂度O(n)
    
    0 赞同 0 条回复
  • 庄重 普通 2022年10月21日 下午10:39
    // Q1:leetcode里的链表,头结点都是储存数据的吗?
    // Q2:这道题没有明确指明数据不重复吧?我写的代码编译之后超时,哭~~~
    class Solution {
    public:
        ListNode* deleteNode(ListNode* head, int val) {
            //考虑头结点为空和头结点为为删除值
            if( head == NULL )  return NULL;
            if( head->val == val) return head->next;
    
            ListNode* pPre = head;
            ListNode* pCur = head->next;
            for(; pCur ;){
                if( pCur->val == val ){
                    //删除节点
                    pPre->next = pCur->next;
                    return head;
                }
                pPre = pPre->next;
                pCur = pCur->next;
            }
            return head;     
        }
    };
    //时间复杂度O(n) 最不理想的情况是完全遍历链表
    //空间复杂度O(1)
    
    0 赞同 1 条回复
  • mpweixin用户 普通 2022年10月21日 下午10:13
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            if(head.val == val)             // 头节点value相等,直接返回下一个节点
                return head.next;           
            ListNode p = head;              // 遍历指针
            while(p.next.val != val)        // 遍历链表,直到找到value
                p = p.next;
            if(p.next.next != null)         // 找到的不是尾节点,删除节点后指向下一个节点
                p.next = p.next.next;
            else                            // 找到的是尾节点,删除节点后指向空节点
                p.next = null;
            return head;                    // 返回头节点
        }
    }
    
    0 赞同 0 条回复
  • Asphyxia 普通 2022年10月21日 下午10:12

    思路:遍历列表,找出val,删除。由于需要知道前序节点,所以需要哑节点指向头结点遍历
    下面是代码

    /**
     * struct ListNode {
     *  int val;
     *  struct ListNode *next;
     *  ListNode(int x) : val(x), next(nullptr) {}
     * };
     */
    class Solution {
    public:
        /**
         * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
         *
         * 
         * @param head ListNode类 
         * @param val int整型 
         * @return ListNode类
         */
        ListNode* deleteNode(ListNode* head, int val) {
            // write code here
            ListNode* dump = new ListNode(0);
            dump->next=head;
            ListNode* cur=dump;
            while(cur->next){
                if(cur->next->val==val){
                    cur->next = cur->next->next;
                }
                cur = cur->next;
            }
            return dump->next;
        }
    };
    
    0 赞同 0 条回复
  • 马啸天 永久会员 2022年10月21日 下午9:50
    
    class Solution{
    public ListNode deleteNode(ListNode head , int val) {
       ListNode dummyHead = new ListNode(-1);
       dummyHead.next = head;
       ListNode prev = dummyHead;
        while (prev.next!=null){
            if (prev.next.val==val){
                prev.next=prev.next.next;
                return dummyHead.next;
            }else
                prev=prev.next;
        }
        return dummyHead.next;
    }
    }
    class Solution2 {
        public ListNode deleteNode(ListNode head , int val) {
            //使用递归
            if (head == null)
                return null;
            head.next = deleteNode(head.next , val);
            return head.val == val ? head.next : head;
        }
    }
    class Solution3 {
        public ListNode deleteNode(ListNode head , int val) {
            //没有dummyHead,需要对head单独处理一下
            if (head == null) {
                return null;
            }
            while (head != null && head.val == val) {
                head = head.next;
            }
            ListNode prev = head;
            while (prev.next != null) {
                if (prev.next.val == val) {
                    prev.next = prev.next.next;
                }else
                    prev=prev.next;
            }
            return head;
        }
    }
    
    
    class Solution4{
        public ListNode deleteNode(ListNode head,int val){
            //使用双指针
            if (head==null)
                return null;
            if (head.val==val)
                return head.next;
            //一前一后
            ListNode pre=head;
            ListNode cur=head.next;
    
            while (cur!=null){
                if (cur.val==val){
                    pre.next=cur.next;//跳过cur,就算删除了
                    return head;
                }
                //双指针一起移动
                cur=cur.next;
                pre=pre.next;
            }
            return head;
        }
    }
    
    
    
    0 赞同 0 条回复
  • Haoyun 普通 2022年10月21日 下午9:39

    用虚拟头结点

    var deleteNode = function(head, val) {
      let dummy=new ListNode(0)
      dummy.next=head;
      let cur=dummy; 
      while(cur&&cur.next){
         if(cur.next.val===val){
             cur.next=cur.next.next
         }
         cur=cur.next
      }
      return dummy.next
    };
    
    0 赞同 0 条回复
  • 秊 永久会员 2022年10月21日 下午9:38
    class Solution {
        // 双指针
        public ListNode deleteNode(ListNode head, int val) {
            if (head.val == val) return head.next;
    
            ListNode pre = head;
            ListNode cur = head.next;
            while (cur.val != val) {   // 假设val值一定存在
                pre = cur;
                cur = cur.next;
            }
            pre.next = cur.next;
    
            return head;
        }
    }
    
    0 赞同 0 条回复
  • MR.SandMan 普通 2022年10月21日 下午9:24
    class Solution {
        public void deleteNode(ListNode pListHead, ListNode pToBeDeleted) {
            ListNode pre = new ListNode(0);
            ListNode cur = pListHead;
            pre.next = pListHead;
            while (cur != pToBeDeleted) {
                cur = cur.next;
                pre = pre.next;
            }
            pre.next = cur.next;
        }
    }
    

    先后两个节点从头节点开始遍历,前面的节点为目标节点的话,后节点的next为前节点的next。

    0 赞同 0 条回复
  • lobort 普通 2022年10月21日 下午9:08

    “`java
    class Solution {
    public ListNode deleteNode(ListNode head, int val) {
    if(head.val == val) {
    return head.next;
    }
    //定义指针的前后点
    ListNode pre = head, cur = head.next;
    //注意别用节点去和val 比较 这里错了 好久
    while(cur.val != val){
    pre = cur;
    cur = cur.next;
    }
    //相等的时候 跳过当前节点
    if(cur.val ==val){
    pre.next = cur.next;
    }
    return head;
    }
    }

    0 赞同 0 条回复
  • T 普通 2022年10月21日 下午9:06

    下面是代码

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            if(head.val == val) 
                return head.next; 
            ListNode pre = new ListNode(0);
            ListNode cur = head;
            while(cur != null) {
                if(cur.val == val) 
                    pre.next = cur.next;
                pre = cur;
                cur = cur.next;
            }
            return head;
        }
    }
    
    0 赞同 0 条回复
  • So 普通 2022年10月21日 下午8:59

    第一天第一题

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            if (head == null) {
                return null;
            }
            if (head.val == val) {
                return head.next;
            }
            ListNode temp = head.next;
            ListNode pre = head;
            while (temp != null) {
                if (temp.val == val) {
                    pre.next = temp.next;
                    return head;
                }
                temp = temp.next;
                pre = pre.next;
            }
            return head;
        }
    }
    
    0 赞同 0 条回复
  • 天会亮、心会暖 永久会员 2022年10月21日 下午8:45
    // 删除链表的节点
    // 1.头节点
    // 2.非头节点
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            //如果为头节点,直接返回头节点的下一节点
            if(head.val == val) return head.next;
            ListNode pre = head, cur = pre.next;
            //如果为非头节点,判断头节点的下一结点是否为空,并不断循环
            while(cur != null && cur.val != val) {
                pre = cur;
                cur = cur.next;
            }
            // 循环退出,val即为此时cur节点的val值,所有把cur的下一节点替换为pre的下一结点,此时cur不在链表中
            if(cur != null) {
                pre.next = cur.next;
            }
            return head;
        }
    }
    
    0 赞同 1 条回复
  • wxc 普通 2022年10月21日 下午8:37

    额

    class Solution:
        def deleteNode(self, head: ListNode, val: int) -> ListNode:
            if(head <span class="text-highlighted-inline" style="background-color: #fffd38;"> None):
                return None
            elif(head.val </span> val):
                return head.next
            else:
                x1 , x2 = head , head.next
                while(x1 and x2.val != val):
                    x1 , x2 = x2 , x2.next
                if x2 :
                    x1.next = x2.next
                return head
    
    0 赞同 0 条回复
  • symbol 普通 2022年10月21日 下午8:30
    //golang 递归 
    func deleteNode(head *ListNode, val int) *ListNode {
        //递归结束条件
        if head.Val == val {
            return head.Next
        }
        head.Next = deleteNode(head.Next, val) // 本层逻辑
        return head
    }
    
    0 赞同 0 条回复
  • 糖香香 普通 2022年10月21日 下午8:26
    class Solution {
    
        public ListNode deleteNode(ListNode head, int val) {
    //删除头节点时,直接返回head.next即可
            if(head.val == val) 
    
                return head.next;
    
            ListNode pre = head, cur = head.next;
    //循环定位节点
            while(cur != null && cur.val != val){
    
                pre = cur;
    
                cur = cur.next;
    
            }
    //删除节点
            if(cur != null)
    
                pre.next = cur.next;
    
            return head;
    
        }
    
    0 赞同 0 条回复
  • 如梦似歌 普通 2022年10月21日 下午8:24
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            //如果要删除的节点是头节点的话,直接返回头结点的下一个节点即可
            if(head.val  == val){
                head = head.next;
                return head;
            }
            //如果要删除的节点不是头结点的话,定义2个指针p,r,遍历r指针找到要删除的那个节点即可
            ListNode p = head;
            ListNode r = p.next;
            while(r.val != val){
                p = r;
                r = r.next;
            }
            p.next = r.next;
            return head;
        }
    }
    
    0 赞同 0 条回复
  • 狗蛋儿 普通 2022年10月21日 下午8:23
    class Solution {
    public:
        ListNode* deleteNode(ListNode* head, int val) {
            ListNode *mypi = new ListNode(0);
            mypi->next = head;
            ListNode *cur = mypi;
            while(cur->next != NULL){
                if(cur->next->val == val){
                    ListNode *tmp = cur->next;
                    cur->next = tmp->next;
                    delete tmp;
                }else cur = cur->next; 
            }
            head = mypi->next;
            delete mypi;
            return head;
        }
    };
    

    这里就是使用了一个虚拟头结点,来简化出现上来就要删除的这种情况!

    0 赞同 0 条回复
  • xye 普通 2022年10月21日 下午8:17
    func deleteNode(head *ListNode, val int) *ListNode {
        if head.Val == val {
            return head.Next
        }
    
        pre:=head
        for head.Next.Val != val{
            head = head.Next
        }
        head.Next = head.Next.Next
        return pre
    
    }
    

    初级,熟悉语言

    0 赞同 0 条回复
  • 天然 普通 2022年10月21日 下午8:17

    好久没写有些忘记了

    class Solution(object):
        def deleteNode(self, head, val):
            """
            :type head: ListNode
            :type val: int
            :rtype: ListNode
            """
    
            cur = head
            tex = ListNode
            if cur.val==val:
                head = cur.next
                del cur
                return head
            while cur.val!=val:
                tex=cur
                cur= cur.next
            tex.next = cur.next
            del cur
            return head
    
    
    0 赞同 0 条回复
  • @ 普通 2022年10月21日 下午8:16

    递归

    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            if(head== null)
                return null;
    
            ListNode res = deleteNode(head.next, val);
    
            if(head.val == val)
                return res;
            else{
                head.next = res;
                return head;
            }
    
        }
    }
    
    0 赞同 0 条回复
  • 西西弗斯的石头 永久会员 2022年10月21日 下午8:14

    简单

    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            if(head == null||head.next == null){
                return null;
            }
            if(head.val == val) return head.next;
            ListNode i = head;
            ListNode temp = head.next;
            while(temp!=null){
                if(temp.val ==  val){
                    i.next = temp.next;
                }
                i = i.next;
                temp = temp.next;
            }
            return head;
        }
    }
    
    0 赞同 0 条回复
  • 一只骆驼 普通 2022年10月21日 下午8:11

    先判断头节点

    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            if(head.val==val) return head.next;
            ListNode cur = head;
            while(cur.next!=null){
                if(cur.next.val==val){
                    cur.next=cur.next.next;
                    return head;
                }
                cur = cur.next;
            }
            return head;
        }
    }
    
    0 赞同 1 条回复
  • zjl 普通 2022年10月21日 下午8:07

    前置一个自定义节点,双指针共同移动即可!

        public ListNode deleteNode(ListNode head, int val) {
            ListNode pre = new ListNode();
            pre.next = head;        
            ListNode p2 = head;   
            ListNode p1 = pre;
            while(p2.val != val){
                p1 = p2;
                p2 = p2.next;
            }    
            // del
            p1.next = p2.next;
            return pre.next;
        }
    
    0 赞同 0 条回复
  • 1ue1uekin8 普通 2022年10月21日 下午8:05

    对开头就是要删除的数据特判

    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            if (head.val == val) return head.next;
            ListNode tmp = head;
            while(tmp.next.next != null) {
                if (tmp.next.val == val) break;
                tmp = tmp.next;
            }
            tmp.next = tmp.next.next;
            return head;
        }
    }
    
    0 赞同 0 条回复
  • 194分贝 普通 2022年10月21日 下午8:02

    /*
    * 删除结点时,指针需指向待删除结点的上一个结点。
    * 因为可能恰好删除的是头结点,所以可以创建一个虚拟节点放在头结点前面,成为虚拟头结点。
    */

    class Solution {
      public:
        ListNode* deleteNode(ListNode* head, int val) {
            ListNode* virtualHead = new ListNode(0); // 创建虚拟结点
            virtualHead->next = head; // 虚拟结点的next指针指向链表头结点
            ListNode* p = virtualHead; // 从虚拟结点开始遍历链表
            while (p) {
                if (p->next->val == val) {
                    ListNode* temp = p->next;
                    p->next = p->next->next;
                    delete temp;
                    break;
                } else p = p->next;
            }
            return virtualHead->next;
        }
    };
    
    1 赞同 0 条回复
  • 青木 普通 2022年10月21日 下午8:01
    //有头结点版本,自己写的;
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            ListNode root = new ListNode();
            root.next = head;      //自制头结点指向head
            ListNode p1 = root;
            ListNode p2 = head;
    
            while(p2 != null && p2.val != val){
                p1 = p2;
                p2 = p2.next;
            }
            if(p2 == null){
                return head;
            }
            else{
                p1.next = p2.next;
                return root.next;
            }
        }
    }
    
    //无头结点版,借鉴了答案;
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            if(head == null){
                return head;
            }
    
            if(head.val == val){
                return head.next;
            }
    
            ListNode pre = head, temp = head.next;
            while(temp != null){
                if(temp.val == val){
                    pre.next = temp.next;
                    return head;
                }
                pre = temp;
                temp = temp.next;
            }
            return head;
        }
    }
    
    0 赞同 2 条回复
  • 忆霁昕 永久会员 2022年10月21日 下午7:58

    删除单链表节点需要获得其前一个节点,用虚拟头结点简化逻辑,题干说明中有链表中节点值不相同的限制,不用判断是否为空链表

    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            //虚拟头结点
            ListNode dummyHead = new ListNode();
            dummyHead.next = head;
    
            //p遍历链表
            ListNode p = dummyHead;
            //删除单链表的节点需要获得该节点的前一个节点
            //p为要删除节点的前一个节点
            while (p.next != null) {
                //删除p的下一个结点
                if (p.next.val == val) {
                    p.next = p.next.next;
                    break;
                }
                p = p.next;
            }
            return dummyHead.next;
        }
    }
    
    0 赞同 0 条回复
  • 王艺超 普通 2022年10月21日 下午7:55

    自己写的没有考虑到head节点为空的情况,也没有将指针置零

    class Solution {
    public:
        ListNode* deleteNode(ListNode* head, int val) {
    
            if(head->val == val)
            {
                head = head->next;
                return head;
            }
            ListNode *q = head;
            while(q->next->val != val)
            {
                q = q->next;
            }
            q->next = q->next->next;
            return head;
        }
    };
    
    0 赞同 0 条回复
  • Chin 普通 2022年10月21日 下午7:49
    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            if(head == null) return null;
    
            ListNode dummyNode = new ListNode(0);
            dummyNode.next = head;
            ListNode pre = dummyNode;
            //  以上代码是虚拟节点,为了好遍历链表的头结点
    
            while(pre.next != null){
                if(pre.next.val == val){
                    //  直接把该节点从链条上断掉(当前节点的 前节点 指向 它的下节点)
                    pre.next = pre.next.next;
                    break;
                }
                //  指针引用遍历往后推 
                pre = pre.next;
            }
            //  返回头结点
            return dummyNode.next;
        }
    }
    

    第一次提交while 忘记写break跳出了…

    0 赞同 0 条回复
  • Whatever 永久会员 2022年10月21日 下午7:43

    注意判空和目标值为头结点的情况

    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            if(head == null){
                return null;
            }
            if(head.val == val){
                return head.next;
            }
            ListNode p = head;
            while(p.next != null){
                if(p.next.val == val){
                    p.next = p.next.next;
                    continue;
                }else{
                    p = p.next;
                }
            }
            return head;
        }
    }
    
    0 赞同 0 条回复
  • 宁 永久会员 2022年10月21日 下午7:34

    第一次提交忘记写pre = pre.next;导致超出时间限制。

    class Solution {
        public ListNode deleteNode(ListNode head, int val) {
            if(head == null)
                return null;
            if(head.val == val){
                head = head.next;
                return head;
            }
            ListNode pre = head;
            while(pre.next != null){
                if(pre.next.val == val){
                    pre.next = pre.next.next;
                    return head;
                }
                pre = pre.next;
            }
            return head;
        }
    }
    
    1 赞同 0 条回复
  • mpweixin用户 普通 2022年10月21日 下午7:28

    删除链表的结点,直接将结点指向下一结点,注意链表尾部判空。

    public void deleteNode(ListNode node){
              while(node.next != null){
                       node.val = node.next,val;
                      if(node.next.next==null){
                         node.next = null;
                         break;
                       }else{
                          node = node.next;
    }}}
    
    0 赞同 0 条回复

# 回答此问题

后才能回答