代码随想录Day4 | 链表02-leetcode24、19、面试题02.07、142

这篇具有很好参考价值的文章主要介绍了代码随想录Day4 | 链表02-leetcode24、19、面试题02.07、142。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

24-两两交换链表中的节点

题目链接:两两交换链表中的节点

思路:双指针p1、p2,分别指向每次需要交换的节点。交换过程为p2的next指向p1,p1的next指向p2的next,还需要注意将p1de前一个指针指向交换后的p2以确保不断链

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if(head == nullptr || head -> next == nullptr)
            return head;
        else{
            ListNode *p1 = head;
            ListNode *dummy_head = new ListNode(0); // 虚拟头结点
            dummy_head->next = head;
            ListNode *prev = dummy_head; // 虚拟头结点
            while(p1 != nullptr && p1->next != nullptr){
                ListNode *p2 = p1->next;
                if(p2 != nullptr){
                    ListNode *temp = p2->next;
                    prev->next = p2;
                    p1->next = temp;
                    p2->next = p1;
                    prev = p1;
                    p1 = p1->next;
                }else break;
            }
            return dummy_head->next;
        }
        
    }
};

1. 空链 or 只有头结点?

- 直接返回head,无需做任何修改

2. 交换需要记录前驱节点,而头节点无前驱?

- 添加虚拟头节点


19-删除链表中的倒数第N个节点

题目链接:删除链表中的倒数第N个结点

1.暴力解法

算法描述:遍历两次,第一次获取链长,第二次得到待删除结点及其前驱结点。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        // 暴力解法:遍历两遍,第一遍获取链长,第二遍获取删除结点
        int len = 0;//记录链长
        ListNode *dummyhead = new ListNode();
        dummyhead->next = head; // 添加虚拟头结点

        ListNode *cur = head;
        while(cur != nullptr){
            len++;
            cur = cur->next;
        }

        ListNode *prev = dummyhead;
        cur = dummyhead->next;
        for(int index = len - n; index > 0; index--){
            prev = prev->next;
            cur = cur->next;
        }

        prev->next = cur->next;
        delete cur;

        return dummyhead->next;
    }
};

注意可能删除的结点为头结点,因此需要添加虚拟头结点。

2.双指针法

算法描述:使用快慢指针,先将快指针移动n+1步,此时慢指针即为相对于快指针而言的倒数第n个结点的前驱。同步移动快慢指针,当快指针为链尾时,慢指针指向的结点即为待删除结点。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        // 快慢指针
        ListNode *slow, *fast;
        ListNode *dummyhead = new ListNode();
        dummyhead->next = head;
        slow = dummyhead;
        fast = dummyhead;

        while(n-- && fast != nullptr){
            fast = fast->next;
        }
        fast = fast->next;
        while(fast != nullptr){
            slow = slow->next;
            fast = fast->next;
        }
        ListNode *temp = slow->next;
        slow->next = temp->next;
        delete temp;
        return dummyhead->next;
    }
};

面试题02.07-链表相交

题目链接:链表相交

算法描述:(来自官方题解,真的很巧妙~)双指针从A和B的head处开始移动并判断当前指向的指针是否相等,若相等则返回。若某一指针指向了nullptr则指向另一条链的头结点,继续遍历直至找到公共结点。

解释:当某一指针指向nullptr后转向另一条链的头结点 --> AB链若相交,则从某一结点开始之后的所有结点都相等。当某一指针p1 == nullptr时,另一指针p2走过的长度即为短链的长度,此时继续向后遍历,长链的指针p2也为nullptr时转向短链,此时p1指针未遍历的长度即为短链的长度,由于题意(相加后所有的后续结点都相同),因此从短链的起始位置和长链后半段与短链长度相等的位置开始遍历,总能找到相交的结点。若不存在交点,此时p1和p2也会同时为nullptr。

(短链遍历完之后,找到长链对应的长度。继续遍历长链找到与短链剩余长度相等的位置。从该位置向后遍历寻找交点)

 /**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        if(headA == nullptr || headB == nullptr)
            return nullptr;
        
        ListNode *p1 = headA;
        ListNode *p2 = headB;
        while(p1 != p2){
            p1 = p1 == nullptr ? headB : p1->next;
            p2 = p2 == nullptr ? headA : p2->next;
        }

        return p2;        
    }
};

142-环形链表II

题目链接:环形链表II

1.快慢指针

算法描述:快指针每次走两步,慢指针每次走一步,若快慢指针相遇则存在环。通过快指针一定比慢指针多走整数倍的环的长度这样的等式关系找到环的入口

(待复习) 代码随想录的视频讲解:视频-环形链表  代码随想录文字讲解:文字-环形链表

2.哈希表

算法描述:遍历链表并检查哈希表中是否存在当前结点,若存在即为链表中环的入口,否则加入哈希表中,直至指针指向nullptr

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        //哈希表
        ListNode *cur = head;
        unordered_set<ListNode*> set;
        while(cur != nullptr){
            if(set.find(cur) != set.end()){
                return cur;
            }
            set.insert(cur);
            cur = cur->next;
        }
        return cur;
    }
};

Day5休息日~文章来源地址https://www.toymoban.com/news/detail-658456.html

到了这里,关于代码随想录Day4 | 链表02-leetcode24、19、面试题02.07、142的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【代码随想录】刷题Day4

    24. 两两交换链表中的节点 前后指针实现 1.没有元素或者只有一个元素无意义 2.给出一个前驱prev,以及用来交换的两个节点cur和next 3.我当时是这么想的,如果两个指针一起动,那么就要用cur和next同时判断结束,也许这个条件会比较苛刻(我就烦这种边界条件),所以我觉得动一

    2023年04月22日
    浏览(33)
  • 代码随想录day02

    ● 力扣题目链接 ● 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。 思路 ● 暴力排序,时间复杂度O(n + nlogn) ● 使用双指针,时间复杂度O(n) 代码 ● 力扣题目链接 ● 给定一个含有 n 个正整数的数组和一个正整

    2024年02月13日
    浏览(27)
  • 代码随想录第四天|LeetCode24. 两两交换链表中的节点,LeetCode19.删除链表的倒数第N个节点,LeetCode面试题 02.07. 链表相交,LeetCode142.环形链表II

    LeetCode24. 两两交换链表中的节点 题目链接:24. 两两交换链表中的节点 - 力扣(LeetCode) 思路: 先定义一个虚拟头结点方便操作。 再就是交换相邻两个元素了, 此时一定要画图,不画图,操作多个指针很容易乱,而且要操作的先后顺序 初始时,cur指向虚拟头结点,然后进行

    2024年02月09日
    浏览(29)
  • 代码随想录 Leetcode142. 环形链表 II

            双指针解决百分之99的链表题

    2024年01月19日
    浏览(33)
  • 【代码随想录 | Leetcode | 第七天】链表 | 链表相交 | 环形链表 II

    欢迎来到小K的Leetcode|代码随想录|专题化专栏,今天将为大家带来链表相交和环形链表 II的分享 ✨ ✨题目链接点这里 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。 图示两个链表在节点 c1 开始相交:

    2024年02月17日
    浏览(32)
  • 【代码随想录 | Leetcode | 第五天】链表 | 移除链表元素 | 设计链表 | 203-707

    欢迎来到小K的Leetcode|代码随想录|专题化专栏,今天将为大家带来移除链表元素和设计链表的分享 ✨ ✨题目链接点这里 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。 示例 1: 示例 2: 示例 3: 提示: 列表中

    2024年02月16日
    浏览(45)
  • 代码随想录day3 | 203.移除链表元素 707.设计链表 206.反转链表

    直接让前一个节点指向后一个节点即可 两种方法 第一种:直接删除 第二种:头删的时候,直接 head=head-next 其实这两种方法都没有做到统一 第三种:虚拟头结点法 这样的话,咱们删除的时候,就是以统一的规则来进行删除啦! 203.移除链表元素 法一:原始删除法 1、while(h

    2024年02月16日
    浏览(28)
  • 代码随想录day3|链表理论基础、移除链表元素、设计链表、翻转链表

    1、基本类型:单链表、双链表、循环链表 2、存储方式:和数组不一样,链表是随机存储在内存中,不是连续分配在内存中。 3、链表的定义: 定义了一个数据域,还有一个指针域,并且定义了一个构造函数。 4、链表的操作: 删除节点:  在图中,若需要删除D这个节点,只

    2024年02月05日
    浏览(32)
  • 代码随想录Day1 | 数组01- leetcode 704、27

    题目链接:二分查找 关键问题:         - 边界(left、right)、当前查找值(middle)                 - target大于当前查找值 -- 当前查找区域的右边,更改区间left                 - target小于当前查找值 -- 当前查找区域的左边,更改区间right                 - middle的计

    2024年02月16日
    浏览(27)
  • 代码随想录Day20 回溯算法 LeetCode77 组合问题

    以下内容更详细解释来自于:代码随想录 (programmercarl.com) 回溯法也叫回溯搜索法,是搜索法的一种,我们之前在二叉树中也经常使用到回溯来解决问题,其实 有递归就有回溯 ,有的时候回溯隐藏在递归之下,我们不容易发觉,今天我们来详细介绍一下什么是回溯,它能解决哪些问题.

    2024年02月08日
    浏览(32)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包