【Leetcode解题报告】单链表结点删除相关问题

Leetcode 203 Remove Linked List Elements

问题描述

  Remove all elements from a linked list of integers that have value val. For example, given 1 -> 2 -> 6 -> 3 -> 4 -> 5 -> 6, val = 6. Return 1 -> 2 -> 3 -> 4 -> 5.

分析与解法

  遍历链表,用一个指针指向遍历到当前结点的前驱结点,方便删除;如果当前结点的值为val,则删除。参考代码如下所示:

 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode
 4  * {
 5  *     int val;
 6  *     ListNode *next;
 7  *     ListNode(int x) : val(x), next(NULL) {}
 8  * };
 9  */
10 class Solution
11 {
12 public:
13     ListNode* removeElements(ListNode* head, int val)
14     {
15         ListNode new_head_node(0); new_head_node.next = head;
16         ListNode *pre = &new_head_node, *p = head;
17         while (p)
18         {
19             if (p->val == val)
20             {
21                 ListNode *q = p;
22                 p = p->next;
23                 pre->next = p;
24                 delete q; // 释放结点
25             }
26             else
27             {
28                 pre = p;
29                 p = p->next;
30             }
31         }
32         return new_head_node.next;
33     }
34 };

Leetcode 83 Remove Duplicates from Sorted List

题目描述

  Given a sorted linked list, delete all duplicates such that each element appear only once. For example, given 1 -> 1 -> 2, return 1 -> 2. Given 1 -> 1 -> 2 -> 3 -> 3, return 1 -> 2 -> 3.

分析与解法

  遍历链表,查看当前结点的值是否与其前驱结点相同,如果相同,则删除;否则不删除。参考代码如下:

 1 class Solution
 2 {
 3 public:
 4     ListNode* deleteDuplicates(ListNode* head)
 5     {
 6         if (!head || !head->next) return head;
 7         ListNode *pre = head, *p = head->next;
 8         while (p)
 9         {
10             if (p->val == pre->val)
11             {
12                 ListNode *q = p;
13                 p = p->next;
14                 pre->next = p;
15                 delete q;
16             }
17             else
18             {
19                 pre = p;
20                 p = p->next;
21             }
22         }
23         return head;
24     }
25 };

Leetcode 82 Remove Duplicates from Sorted List II 

问题描述

  Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. For example, given 1 -> 2 -> 3 -> 3 -> 4 -> 4 -> 5, return 1 -> 2 -> 5. Given 1 -> 1 -> 1 -> 2 -> 3, return 2 -> 3.

分析与解法

(1) 非递归解法

  遍历链表,看当前结点值是否与后继结点值相等(如果后继不为空),如果不相等,则继续遍历;否则,删除与当前结点值相同的所有结点,包括当前结点,使用一个指针指向遍历到当前结点的前驱结点,方便进行删除操作。参考代码如下:

 1 class Solution
 2 {
 3 public:
 4     ListNode* deleteDuplicates(ListNode* head)
 5     {
 6         ListNode new_head_node(0); new_head_node.next = head;
 7         ListNode *pre = &new_head_node, *p = head;
 8         while (p && p->next)
 9         {
10             if (p->val != p->next->val)
11             {
12                 pre->next = p;
13                 pre = p;
14                 p = p->next;
15             }
16             else
17             {
18                 while (p && p->next && p->val == p->next->val)
19                 {
20                     ListNode *q = p;
21                     p = p->next;
22                     delete q;
23                 }
24                 if (p)
25                 {
26                     ListNode *q = p;
27                     pre->next = p->next;
28                     p = p->next;
29                     delete q;
30                 }
31                 else pre->next = NULL;
32             }
33         }
34         return new_head_node.next;
35     }
36 };

(2) 递归解法

  一个看起来更容易理解的方法,参考代码如下:

 1 class Solution
 2 {
 3 public:
 4     ListNode* deleteDuplicates(ListNode* head)
 5     {
 6         if (!head || !head->next) return head;
 7         ListNode *p = head;
 8         if (p->val != p->next->val)
 9         {
10             p->next = deleteDuplicates(p->next);
11             return head;
12         }
13         else
14         {
15             while (p->next && p->val == p->next->val)
16             {
17                 ListNode *q = p;
18                 p = p->next;
19                 delete q;
20             }
21             ListNode *q = p->next;
22             delete p;
23             return deleteDuplicates(q);
24         }
25     }
26 };

Leetcode 19 Remove Nth Node fron End of List

问题描述

  Given a linked list, remove the Nth node from the end of list and return its head. For example, given linked list: 1 -> 2 -> 3 -> 4 -> 5, and n = 2. After removing the second node from the end, the linked list becomes 1 -> 2 -> 3 -> 5.

  Note: given n will always be valid. Try to do this in one pass.

分析与解法

  经典的快慢指针问题,先用快慢指针找到倒数第n个结点的前驱结点,然后删除,参考代码如下所示:

 1 class Solution
 2 {
 3 public:
 4     ListNode* removeNthFromEnd(ListNode* head, int n)
 5     {
 6         ListNode *nhead = new ListNode(0); nhead->next = head;
 7         ListNode *p = head, *q = nhead, *s = NULL;
 8         for (int i = 0; i < n; i++) p = p->next;
 9         while (p)
10         {
11             p = p->next;
12             q = q->next;
13         }
14         s = q->next;
15         q->next = s->next;
16         delete s;
17         return nhead->next;
18     }
19 };

Leetcode 237 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 -> 4 after calling your function.

分析与解法  

  在删除结点时,如果我们知道要删除结点的前驱结点,那么,删除这个结点将比较容易,换句话说,删除一个结点的后继结点是比较容易实现的;而本题并不知道前驱,也没有办法获得前驱结点的位置。可以换一个思路,将当前结点的后继删除,这是比较容易做到的,不过,在删除其后继结点之前,需要将后继结点的值赋给当前结点,这样虽然删除的是其后继,但实际保留了后继的值,删除了当前结点的值。参考代码如下所示:

 1 class Solution {
 2 public:
 3     void deleteNode(ListNode* node)
 4     {
 5         node->val = node->next->val;
 6         ListNode *s = node->next;
 7         node->next = s->next;
 8         delete s;
 9     }
10 };

时间: 2024-10-06 18:30:27

【Leetcode解题报告】单链表结点删除相关问题的相关文章

习题11-8 单链表结点删除 (20分)

习题11-8 单链表结点删除 (20分) 本题要求实现两个函数,分别将读入的数据存储为单链表.将链表中所有存储了某给定值的结点删除.链表结点定义如下: struct ListNode { int data; ListNode *next; }; 函数接口定义: struct ListNode *readlist(); struct ListNode *deletem( struct ListNode *L, int m ); 函数readlist从标准输入读入一系列正整数,按照读入顺序建立单链表

【Leetcode解题报告】数组元素删除

Leetcode 27 Remove Element 问题描述 Given an array and a value, remove all instances of that value in place and return the new length. Do not allocate extra space for another array, you must do this in place with constant memory. The order of elements ca

【LeetCode-面试算法经典-Java实现】【083-Remove Duplicates from Sorted List(排序的单链表中删除重复的结点)】

[083-Remove Duplicates from Sorted List(排序的单链表中删除重复的结点)] [LeetCode-面试算法经典-Java实现][所有题目目录索引] 原题 Given a sorted linked list, delete all duplicates such that each element appear only once. For example, Given 1->1->2, return 1->2. Given 1->1->2

两种删除单链表结点的实现,一种O(n),一种O(1)

常规的删除单链表结点的做法是挨个查找到该结点的前一个结点,然后去掉要删除的这个结点,回收内存.这个需要O(n)的时间. 有一种比较快速的删除掉链表指定一个节点的方法,就是把下一个结点的内容复制到当前这个结点,然后把下一次结点删除掉,这个需要考虑当要删除的结点是最后一个结点的情况. 如果刚好是最后一个结点,则需要O(n)的时间,如果不是最后一个结点,可以在O(1)时间内完成删除操作. 1 // 2 // main.c 3 // SingleListDeleteNode 4 // 5 // Crea

时间复杂度分别为 O(n)和 O(1)的删除单链表结点的方法

有一个单链表,提供了头指针和一个结点指针,设计一个函数,在 O(1)时间内删除该结点指针指向的结点. 众所周知,链表无法随机存储,只能从头到尾去遍历整个链表,遇到目标节点之后删除之,这是最常规的思路和做法. 如图所示,删除结点 i,那么只需找到 i 的前驱 h,然后连 h 到 j,再销毁i 即可.虽然可以安全的删除 i 结点,但是是顺序查找找到 i,之后删除,时间复杂度是 O(n)级别的.具体做法就是:顺序查找整个单链表,找到要删除结点 i 的直接前驱 h,把 h额 next 指向i 的 nex

在O(1)时间内删除单链表结点

// 在O(1)时间内删除单链表结点 /* 思考: 很显然链表是一个节点地址不连续的存储结构 删除节点一般很容易会想到是修改p节点的前一个节点的next为p->next 然而除非是双向链表,否则无法在常量级的时间里找到p的前节点 转变思路: 既然改变不了p前节点的next 只能在p 本身动手脚 那可以考虑修改p->data 使得p->data的值为p->next->data的值,同样可以达到效果 */ #include <iostream> #include &l

【Leetcode解题报告】

第1章  单链表 1.1  删除单链表中的结点 203 Remove Linked List Elements 83  Remove Duplicates from Sorted List 82  Remove Duplicates from Sorted List II 19  Remove Nth Node from End of List 237 Delete Node in a Linked List 1.2  单链表结点位置调整 206 Reverse Linked List 92  

leetCode解题报告5道题(九)

题目一:Combinations Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. For example,If n = 4 and k = 2, a solution is: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ] 分析: 题意给我们一个数字n, 和一个数字k,让我们求出从 1~~n中取出k个数所能得到的组合数 所

LeetCode解题报告:Linked List Cycle &amp;&amp; Linked List Cycle II

Linked List Cycle Given a linked list, determine if it has a cycle in it. Follow up:Can you solve it without using extra space? Linked List Cycle II Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Follo