单手杀穿经典链表题Pt.1——LeetCode天梯渡劫(移除节点,反转链表,中间节点)

简介: 移除链表元素🤔

image.png

思路:

我的评价是有手就行,就相当于链表的删除操作,进行遍历,遍历过程中找到目标值进行覆盖就行,注意一下这里我们采用哨兵位节点,也称为哑节点,开辟出来指向链表头节点,可以使对头节点的操作变简单很多,这个哨兵位节点的值可以不考虑,他只是用来攀搭头结点的舔狗(呜呜)。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 struct ListNode* removeElements(struct ListNode* head, int val){
    struct ListNode* dummyHead = malloc(sizeof(struct ListNode));
    dummyHead->next = head;
    struct ListNode* curr = dummyHead;//定义哨兵位节点
    while (curr->next) {
        if (curr->next->val == val) {
            curr->next = curr->next->next;//遍历到目标点进行覆盖
        } 
        else 
        {
            curr = curr->next;
        }
    }
    head = dummyHead->next;
    free(dummyHead); //有借有还,记得归还哨兵位节点和申请的空间  
    return head;
}

反转链表🤔

链接:反转链表

题目:给你单链表的头节点 head ,请你反转链表,并返回反转后的链表

示例 :

输入:head = [1,2,3,4,5]

输出:[5,4,3,2,1]

image.png

思路:

1.创建一个新的中间节点我命名为 next ,将当前节点的下一个节点存放在next 节点中

2.链接 next 和当前节点,将 next 指向 当前节点实现反转,将原来指向下一节点的内容销毁掉(头部指向NIULL即可);

3.重复上述过程即可


以上是整体思路实现,而代码实现我们有两条路可以走,分别是迭代和递归,实现思路是一样的:


迭代:

struct ListNode* reverseList(struct ListNode* head){
struct ListNode* next = NULL;
struct ListNode* prev = NULL;
while(head)
{   
next = head->next;
head->next = prev;
prev = head;
head = next;
}
return prev;
}

递归:

递归又分为了向前递归和向后递归,一般采用从前向后递归:

struct ListNode* reverse(struct ListNode* cur,struct ListNode* prev)
{
if(cur==NULL)
{
    return prev;
}
 struct ListNode* next = cur->next;
cur->next = prev;
return reverse(next,cur); //可以与双指针法对比,其实逻辑是一样的,只是用递归实现而已
}
struct ListNode* reverseList(struct ListNode* head)
{
return reverse(head,NULL);
}

从后向前递归:

struct ListNode* reverseList(struct ListNode* head)
{
if(!head || !head->next)
return head;
struct ListNode* cur =  reverseList(head->next);//反转第二个节点后的所有节点
head->next->next = haed;//反转第二个节点与头节点
head->next = NULL;//头节点处理
return cur;
}

链表的中间结点🤔

链接:链表的中间结点

给定一个头结点为 head 的非空单链表,返回链表的中间结点,如果有两个中间结点,则返回第二个中间结点。

奇数个返回中间节点:

image.png


思路:

方法一就是老老实实去遍历链表,算出链表长度,再找出中间节点位置,走过去返回他,属于暴力求解,笨且效率不高,这里就不做代码展示;

方法二巧用快慢指针,如下图:

image.png

我们定义两个指针,慢指针一次走一步,快指针一次走两步,不管链表节点数是奇是偶,慢指针最后必定落在中间节点;当链表节点为偶数个时,最后快指针将落在最后一个节点上,所以只需要判断快指针的 next 节点为不为空即可

struct ListNode* middleNode(struct ListNode* head){
    struct ListNode* guard = malloc(sizeof(struct ListNode));
    guard->next = head;//定义哨兵位节点
struct ListNode* fast = guard;
struct ListNode* slow = guard;
while(fast)
{
    slow = slow->next;//慢指针一次走一步
    if(fast->next)
    {
    fast = fast->next->next;//快指针一次走两步
    }
    else
    {
        return slow;
    }
}
return slow;
}


相关文章
|
1月前
LeetCode第二十四题(两两交换链表中的节点)
这篇文章介绍了LeetCode第24题的解法,即如何通过使用三个指针(preNode, curNode, curNextNode)来两两交换链表中的节点,并提供了详细的代码实现。
17 0
LeetCode第二十四题(两两交换链表中的节点)
|
1月前
Leetcode第十九题(删除链表的倒数第N个节点)
LeetCode第19题要求删除链表的倒数第N个节点,可以通过快慢指针法在一次遍历中实现。
40 0
Leetcode第十九题(删除链表的倒数第N个节点)
|
1月前
(剑指offer)18、删除链表的节点—22、链表中倒数第K个节点—25、合并两个排序的链表—52、两个链表的第一个公共节点(2021.12.07)
(剑指offer)18、删除链表的节点—22、链表中倒数第K个节点—25、合并两个排序的链表—52、两个链表的第一个公共节点(2021.12.07)
46 0
|
1月前
【LeetCode 46】450.删除二叉搜索树的节点
【LeetCode 46】450.删除二叉搜索树的节点
15 0
|
6月前
【移除链表元素】LeetCode第203题讲解
【移除链表元素】LeetCode第203题讲解
|
5月前
|
存储 SQL 算法
LeetCode力扣第114题:多种算法实现 将二叉树展开为链表
LeetCode力扣第114题:多种算法实现 将二叉树展开为链表
|
5月前
|
存储 SQL 算法
LeetCode 题目 86:分隔链表
LeetCode 题目 86:分隔链表
|
5月前
|
存储 算法 Java
【经典算法】Leetcode 141. 环形链表(Java/C/Python3实现含注释说明,Easy)
【经典算法】Leetcode 141. 环形链表(Java/C/Python3实现含注释说明,Easy)
52 2
|
6月前
<数据结构>五道LeetCode链表题分析.环形链表,反转链表,合并链表,找中间节点.
<数据结构>五道LeetCode链表题分析.环形链表,反转链表,合并链表,找中间节点
53 1
|
5月前
|
算法
【经典LeetCode算法题目专栏分类】【第7期】快慢指针与链表
【经典LeetCode算法题目专栏分类】【第7期】快慢指针与链表