LeetCode——链表简单题题解

这篇具有很好参考价值的文章主要介绍了LeetCode——链表简单题题解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

83. 删除排序链表中的重复元素

题目描述

给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。
LeetCode——链表简单题题解

输入:head = [1,1,2]
输出:[1,2]

解题思路:用一个指向节点类型的指针保存头结点,用另一个指向节点类型的指针对该链表进行遍历,由于是有序的,当出现不同的值就说明不会再出现跟前面的值相同的节点了,最后循环结束的条件是遍历到最后一个节点的时候,也就是该节点的next 指向空的时候,停止循环,返回该保存的头结点,另外,如果传过来的头结点是空,则直接返回空。

参考代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* deleteDuplicates(struct ListNode* head){

if(!head)//如果head为空直接返回
{
    return head;
}
        struct ListNode* ret = head;//保存头结点
        while(head->next!=NULL)//当head为尾节点时停下来
        {
            if(head->val!=head->next->val)//判断两个相邻节点的值是否相等,如果不相等,head就往后走
            {
               head = head->next;
                continue;
            }
            //如果想等,直接跳过这个节点,相当于删除
             head->next = head->next->next;
            
        }
        return ret;
}

141.环形链表

题目描述
给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

如果链表中存在环 ,则返回 true 。 否则,返回 false 。
LeetCode——链表简单题题解

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

LeetCode——链表简单题题解

输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。

LeetCode——链表简单题题解

输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

解题思路:
这个题我们可以用一个快慢指针来写,这里可以考虑到一个追及问题,如果该链表没有环,则快指针永远不可能和慢指针相遇,而最后会走到末尾,如果有环,那么因为快指针永远比慢指针快一步,并且他们之间是有距离的,所以一定会相遇。

参考代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
bool hasCycle(struct ListNode *head) {
    struct ListNode * fast = head;
    struct ListNode * slow = head;
    while(fast&&fast->next)
    {
        slow = slow->next;//慢指针,一次走一步
        fast = fast->next->next;//快指针一次走两步
        if(slow==fast)
        {
            return true;//一旦相遇说明有环
        }
    }
    return false;
}

面试题02.07 链表相交

题目描述
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。

图示两个链表在节点 c1 开始相交:
LeetCode——链表简单题题解
题目数据 保证 整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构
LeetCode——链表简单题题解

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at ‘8’
解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。

LeetCode——链表简单题题解

输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Intersected at ‘2’
解释:相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。
在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。

LeetCode——链表简单题题解

输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
输出:null
解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。
由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。
这两个链表不相交,因此返回 null 。

解题思路:让pA从headA链表的头节点,pB从headB链表的头结点同时开始走,当走到空的时候就让另一条链表的头结点赋值给相应的节点,比如pA把headA都走完了还没有与pB相等,则把headB赋值给pA让pA继续走下去,同理pB从另一边这样走,就相当于如果两条链表有交点则这两条链表可以看成打了节的绳子,从一个左往右走,一个从右往左走,如果有交点,则pA和pB必然相遇,否则没有交点。

参考代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
            if(headA==NULL||headB==NULL)
            return NULL;

            struct ListNode* pA = headA;
            struct ListNode* pB = headB;
            while(pA!=pB)
            {
                pA = pA!=NULL?  pA->next:headB;
                pB = pB!=NULL? pB->next:headA;
            }

            return pA;
}

206.反转链表

题目描述
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
LeetCode——链表简单题题解

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

有两种方法可以写

方法一:把箭头掰成指向自己前面的节点
如上图所示,很形象的其实
参考代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* reverseList(struct ListNode* head) {
     //方法一
     if(head==NULL)
     {
         return NULL;
     }

     //初始条件
     struct ListNode *n1 = NULL,*n2 = head,*n3 = n2->next;
     //结束条件
     while(n2)
     {
         n2->next = n1;//把当前节点的下一个指向前面的那个节点,相当于形象的掰指针箭头方向
         n1 = n2;
         n2 = n3;
         if(n3)
         {
             n3 = n3->next;
         }
     }
     return n1;//走到最后的n1就是该链表的头结点

方法二:头插法
解题思路:
头插法特性:
可以把先头插的节点都可以挤到后面去,后面头插的节点放到最前面

参考代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* reverseList(struct ListNode* head){
     
        //方法二
        struct ListNode* cur = head;
        struct ListNode* newhead = NULL;
        while(cur)
        {
            struct ListNode* next = cur->next;
            //头插
            cur->next = newhead;
            newhead = cur;
            cur = next;
        }
        return newhead;
        
}

21.合并两个有序链表

题目描述

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的
LeetCode——链表简单题题解

输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]

示例二:

输入:l1 = [ ], l2 = [ ]
输出:[ ]

解题思路:
定义一个新的头节点初始化为空,用两个节点指针分别从两个有序链表的头结点开始遍历并且比较两个节点的值,一 一比较,小的直接尾插到新的头结点后面,直接遍历下去,直到其中一个链表遍历完,然后把另一个链表剩下的节点直接链接到新链表的后面,如果两个链表其中一个为空,那么就直接返回另一个链表。

参考代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){

    if(list1==NULL)
    {
        return list2;
    }
    if(list2==NULL)
    {
        return list1;
    }
    struct ListNode *tail = NULL;
    struct ListNode *head = NULL;
    if(list1->val<list2->val)
    {
        head = tail = list1;
        list1 = list1->next;
    }
    else
    {
        head = tail = list2;
        list2 = list2->next;
        
    }
    while(list1!=NULL&&list2!=NULL)
    {
        if(list1->val<list2->val)
        {
            tail->next = list1;
          list1 = list1->next;
             
        }
        else
        {
             tail->next = list2;
             list2 = list2->next;
        }
       
        tail = tail->next;
    }
    if(list1)
    {
        tail->next = list1;
    }
    if(list2)
    {
        tail->next = list2;
    }
    return head;
}

234. 回文链表

题目描述
给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。

LeetCode——链表简单题题解

输入:head = [1,2,2,1]
输出:true

LeetCode——链表简单题题解

输入:head = [1,2]
输出:false

解题思路:
我是通过快慢指针先找到中间节点,然后再通过调用前面的反转链表的函数,把后半部分进行反转,然后一一对比,直到比到中间节点如果还相等则为回文链表

参考代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* reverseList(struct ListNode* head){
         if(head==NULL)
            return NULL;
         struct ListNode* prev = NULL;   
        struct ListNode* cur = head;
        struct ListNode* last = cur->next;
        head->next = NULL;
        while(cur)
        {
            cur->next = prev;
            prev = cur;
            cur = last;
            if(last)
            {
                last = last->next;
            }
        }
        return prev;

}

bool isPalindrome(struct ListNode* head){
        if(head==NULL||head->next==NULL)
            return true; 
        struct ListNode* low = head;
        struct ListNode* fast = head;
        if((low->next->next)==NULL)
        {
            if(low->val!=low->next->val)
            {
                return false;
            }
            else
            return true;
        }
        while((fast!=NULL)&&(fast->next!=NULL))
        {
            low = low->next;
            fast = fast->next->next;
        }
        struct ListNode* cur = low;
       struct ListNode* newhead =  reverseList(cur);
       while(newhead!=low->next)
       {
           if(newhead->val!=head->val)
           {
               return false;
           }
           head = head->next;
           newhead = newhead->next;
       }
       return true;

}

面试题 02.02. 返回倒数第 k 个节点

题目描述
实现一种算法,找出单向链表中倒数第 k 个节点。返回该节点的值。

示例:

输入: 1->2->3->4->5 和 k = 2
输出: 4

解题思路:定义一个快慢指针先让快指针从头走k步到第k个节点,然后再让慢指针从头开始走,直到快指针走到最后一个空节点为止
相当于快指针先走了k步,然后快指针又走了链表长度-k次,其实这个步数也就是慢指针走的步数,也就是链表的倒数第k个节点

参考代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


int kthToLast(struct ListNode* head, int k){

        struct ListNode* fast = head;
        struct ListNode* low = head;

        while(k--)
        {
            fast = fast->next;
        }

        while(fast)
        {
            fast = fast->next;
            low = low->next;
        }

        return low->val;
}

总结

真的,不说别的,咋们就是说是不是链表这块动不动就用快慢指针,把快慢指针学会并且灵活应用,解答链表题对你会有很大帮助。文章来源地址https://www.toymoban.com/news/detail-426961.html

到了这里,关于LeetCode——链表简单题题解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • LeetCode.82 删除排序链表中的重复元素 二

    LeetCode.82 删除排序链表中的重复元素 二 题目 思路: 1,提供的是无空头链表,需要加一个头结点来统一操作 2,使用三个工作指针 r:记录前一个节点,方便删除操作 p:记录此基准节点 q:前进节点 两种情况: 一 如果p与q不同,则p,q,r,均前进; 二 如果p与q相同,则q前进,

    2024年01月19日
    浏览(32)
  • Killing LeetCode [83] 删除排序链表中的重复元素

    给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。 Ref Link:https://leetcode.cn/problems/remove-duplicates-from-sorted-list/ Difficulty:Easy Tag:LinkedList Updated Date:2023-08-02 示例1: 示例 2: 提示: 链表遍历 Accepted 复杂度分析 时间复杂度:

    2024年02月14日
    浏览(41)
  • LeetCode——82. 删除排序链表中的重复元素II

    通过万岁!!! 题目:题目的大致意思就是,给你一个升序的链表,然后让你里面的元素有重复的,所有重复的元素都进行一个删除。 思路:这个题的简化版是“83.删除排序链表中的重复元素”。看到链表的题目可以优先考虑一下双指针。这里因为head也有可能跟下面的重复

    2024年01月16日
    浏览(39)
  • LeetCode - #82 删除排序链表中的重复元素 II

    我们社区陆续会将顾毅( Netflix 增长黑客,《iOS 面试之道》作者,ACE 职业健身教练。 )的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 LeetCode 算法到目前我们已经更新了 82 期,我们会保持更新时间和进度( 周一、周三、周五早上 9:00 发布 ),每期的内容不多,

    2024年02月10日
    浏览(31)
  • 【Leetcode -21.合并两个有序链表 -83.删除排序链表中的重复元素】

    题目:将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1: 输入:l1 = [1, 2, 4], l2 = [1, 3, 4] 输出:[1, 1, 2, 3, 4, 4] 示例 2: 输入:l1 = [], l2 = [] 输出:[] 示例 3: 输入:l1 = [], l2 = [0] 输出:[0] 我们的思路是,先定义

    2023年04月24日
    浏览(35)
  • leetcode做题笔记83删除排序链表中的重复元素

    给定一个已排序的链表的头  head  ,  删除所有重复的元素,使每个元素只出现一次  。返回  已排序的链表  。   本题与上题相似,但非将所有重复的元素删除,而是将多的重复元素删除,可添加判断语句判断前一个与后一个val值是否相等来决定是否放入链表中,最后输

    2024年02月12日
    浏览(27)
  • ​LeetCode解法汇总82. 删除排序链表中的重复元素 II

    https://github.com/September26/java-algorithms 给定一个已排序的链表的头  head  ,  删除原始链表中所有重复数字的节点,只留下不同的数字  。返回  已排序的链表  。 示例 1: 示例 2: 提示: 链表中节点数目在范围  [0, 300]  内 -100 = Node.val = 100 题目数据保证链表已经按升序  排

    2024年01月17日
    浏览(34)
  • leetcode做题笔记82删除排序链表中的重复元素 II

    给定一个已排序的链表的头  head  ,  删除原始链表中所有重复数字的节点,只留下不同的数字  。返回  已排序的链表  。 本题将重复的元素全部删除,可以考虑新建一个链表,若有重复元素则不放入新链表中,最后输出新链表即可。链表操作需要用另一个链表记录原来

    2024年02月12日
    浏览(45)
  • 算法leetcode|83. 删除排序链表中的重复元素(rust重拳出击)

    给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。 链表中节点数目在范围 [0, 300] 内 -100 = Node.val = 100 题目数据保证链表已经按升序 排列 面对这道算法题目,二当家的再次陷入了沉思。 本来要删除重复元素,需要两次遍

    2024年02月07日
    浏览(28)
  • 算法leetcode|82. 删除排序链表中的重复元素 II(rust重拳出击)

    给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。 链表中节点数目在范围 [0, 300] 内 -100 = Node.val = 100 题目数据保证链表已经按升序 排列 面对这道算法题目,二当家的再次陷入了沉思。 这道题目和 83. 删除排序

    2024年02月08日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包