首页 > 其他分享 >代码随想录第4天 | 24. 两两交换链表中的节点、19.删除链表的倒数第N个节点、面试题 02.07. 链表相交、142.环形链表II

代码随想录第4天 | 24. 两两交换链表中的节点、19.删除链表的倒数第N个节点、面试题 02.07. 链表相交、142.环形链表II

时间:2024-06-08 22:54:55浏览次数:16  
标签:ListNode cur 随想录 next 链表 pA 节点 指针

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

思路:

设置虚拟头结点,双指针+临时指针,(感觉也能递归,未尝试)
时间复杂度:O(n)
空间复杂度:O(1)

坑:

1.又忘了 else{}和return
2.试图访问空指针,多个条件的顺序问题及"&&""||"问题,cur->next要写在cur->next->next前面

/**
 * 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)
            return head;
        else {
            ListNode* dummyhead = new ListNode(0);
            dummyhead->next = head;
            ListNode* cur = dummyhead;
            ListNode* post = head;
            ListNode* pre = new ListNode(0);
            ListNode* tmp;
            while (cur->next!=nullptr&&cur->next->next!=nullptr) {  //优化后,报错,
            /*1. 是“&&”不是“||”, 或的话,若cur->next为nullptr,则cur->next->next就访问空指针了,
              2.cur->next要写在cur->next->next前面,理由同上
            */
                pre = post->next;
                tmp = pre->next;
                cur->next = pre;
                pre->next = post;
                post->next=tmp; //提交heap-use-after-free报错了,我的链表交换后,这里断了,
                cur = post;
                post = tmp;
            }
            return dummyhead->next;
        }
    }
};
/*未优化版本
            while (post!=nullptr) {  //可优化,循环结束条件不对,看循环体结束部分来思考
                pre = post->next;
                if(pre==nullptr){  //缺少判断条件 长度为奇数的链表 这部分可优化
                    return dummyhead->next;
                }
                tmp = pre->next;
                cur->next = pre;
                pre->next = post;
                post->next=tmp; //提交heap-use-after-free报错了,我的链表交换后,这里断了,
                cur = post;
                post = tmp;
            }
*/

补充:

1.heap-use-after-free on address
尾节点如果没有rear->next=NULL;这个链表就会错呢? 尾节点没有明确指向,链表不完整,计算机认为链表未结束
2.悬挂指针(Dangling Pointer)。如果我们试图访问已经被释放的内存,就会触发"heap-use-after-free"错误。

题目:19.删除链表的倒数第N个节点

思路:

1.遍历链表获取链表长度,然后删除结点,释放被删除节点
2.进阶要求是,使用一趟扫描实现-->随想录思路 啊 是快慢指针,快指针先走N+1步,
时间复杂度: O(n)
空间复杂度: O(1)

坑:

试图访问空指针,主要在cur->next时,cur可能为空指针

/** Definition for singly-linked list.同上*/
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* dummyHead=new ListNode(0);
        dummyHead->next=head;
        ListNode* fast=dummyHead;  //fast和slow初始指向虚拟head不是head
        ListNode* slow=dummyHead;
        ListNode* tmp;
        n++; //删除结点,slow要指向被删除结点的前一个节点,所以fast要多走一步,slow和fast相差n+1步
        while(n--&&fast!=nullptr){    //错误,需要判断fast是否为空,
            fast=fast->next;     
        }
        while(fast!=nullptr){  //错误,试图访问空指针 fast不为空 不用->next
            fast=fast->next;
            slow=slow->next;
        }
        tmp=slow->next;
        slow->next=slow->next->next;
        delete tmp;
        return dummyHead->next;
    }
};

补充:

个人对快慢双指针还是没有理解到位
双指针解题:
1.指针相邻:删除某个结点,或交换两个结点
2.指针不相邻,快满指针间隔N步

题目:面试题02.07.链表相交

思路:

1.两个这指针分别指向a,b,两层循环遍历,比较->next是否相等,有点繁琐
2.看了leetcode的引导式提示:从两链表长度相同时相交到不同长度,一个先走差值步,使得二者相同才判断;
时间复杂度:O(n + m)
空间复杂度:O(1)

坑:

  1. 当两链表长度相同时,两链表不相交可以和相交放一起判断
  2. 使用pa->next判空,则少算了最后一个pa节点
  3. 没比较两链表长度,就默认进行下去了;
/** Definition for singly-linked list.同上*/
class Solution {
public:
    ListNode* getIntersectionNode(ListNode* headA, ListNode* headB) {
        ListNode* pA = headA;
        ListNode* pB = headB;

        int m = 0, n = 0, diff = 0; // diff表示两链表的差值 (用英语gap也行)
        pA = headA;                 // 指针返回头结点
        pB = headB;
        while (pA != nullptr) { // 错误,pa->next判空,则少算了最后一个pa节点
            pA = pA->next;
            m++;
        }
        while (pB != nullptr) {
            pB = pB->next;
            n++;
        }
        pA = headA;
        pB = headB;
        // 错误,m和n的大小没有判断,
        if (m < n) { // 交换使得,pA和m表示较长的链表
            swap(pA, pB);
            swap(m, n);
        }
        diff = m - n;
        while (diff--) {
            pA = pA->next;
        }
        while (pA!=nullptr) {
            if(pA==pB)
                return pA;
            pA = pA->next;
            pB = pB->next;
        }
        return NULL;
    }
};

题目:142.环形链表Ⅱ

思路:

坑:

补充:

今日总结

链表类的题主要还是看思路,想得到关键,就后面很顺利

标签:ListNode,cur,随想录,next,链表,pA,节点,指针
From: https://www.cnblogs.com/bamboo2233/p/18239059

相关文章

  • Linux内核链表源代码
    /*SPDX-License-Identifier:GPL-2.0*/#ifndef_LINUX_LIST_H#define_LINUX_LIST_H#include<linux/types.h>#include<linux/stddef.h>#include<linux/poison.h>#include<linux/const.h>#include<linux/kernel.h>/**Simple......
  • 代码随想录算法训练营第三十二天 | 122.买卖股票的最佳时机 55.跳跃游戏 45.跳跃游戏I
    122.买卖股票的最佳时机II题目链接文章讲解视频讲解思路:每次记录当天的股票价格,如果下一天比今天的价钱高那么今天就买,这样保证每一次买股票都是赚的否则记录下一天的股票,因为下一天的股票比今天的便宜,下一天买比今天买划算classSolution{public:intmaxProfit(v......
  • AcWing 33:链表中倒数第k个节点 ← 尾插法
    【题目来源】https://www.acwing.com/problem/content/32/【题目描述】输入一个链表,输出该链表中倒数第k个结点。注意:  ●k>=1;  ●如果k大于链表长度,则返回NULL;【数据范围】链表长度[0,30]。【输入样例】输入:链表:1->2->3->4->5,k=2【输出样例】输出:4......
  • 链表-循环链表
    循环链表可以像链表一样只有单向引用,也可以像双向链表一样有双向引用。循环链表和链表之间唯一的区别在于最后一个元素指向下一个元素的指针(tail.next)不是引用undefined,而是指向第一个元素(head).单链表:this.tail.next=this.head;双向链表:this.tail.next=this.head;......
  • 代码随想录算法训练营第四天 |
    24.两两交换链表中的节点题目:给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。解题:关键:cur的位置在要交换的两个节点的前面具体如何交换的操作!!while种植条件:cur的下一个和下下个都不为空,不......
  • 代码随想录算法训练营第四天 Leetcode 24 两两交换链表节点 Leetcode19 删除链表倒数
    链表问题首先要记住设置虚拟头节点Leetcode24两两交换链表节点题目链接思路:就是简单模拟两两交换 要注意链表节点的处理一定要获取到合适的位置比如:这一题中两个交换节点的前一个节点注意链表保存临时节点/***Definitionforsingly-linkedlist.*publicclas......
  • 代码随想录算法训练营第五十一天| 121. 买卖股票的最佳时机、122.买卖股票的最佳时机I
    121.买卖股票的最佳时机一只股票只能买卖一次代码随想录.-力扣(LeetCode)输入:[7,1,5,3,6,4]输出:5解释:在第2天(股票价格=1)的时候买入,在第5天(股票价格=6)的时候卖出,最大利润=6-1=5。注意利润不能是7-1=6,因为卖出价格需要大于买入价格;同时,你不能在买入......
  • 代码随想录算法训练营第五十天| 198.打家劫舍、213.打家劫舍II、337.打家劫舍 III
    198.打家劫舍文档讲解:代码随想录题目链接:.-力扣(LeetCode) 问题:计算你不触动警报装置的情况下,一夜之内能够偷窃到的最高金额。也就是说相邻的房间不能偷当前房屋偷与不偷取决于前一个房屋和前两个房屋是否被偷了。所以这里就更感觉到,当前状态和前面状态会有一种依赖......
  • 顺序表、链表、栈和队列总结
    目录顺序表链表栈队列总结补充顺序表实现链表实现栈实现队列实现  顺序表、链表、栈和队列都是线性数据结构,但它们在管理和访问数据方面有不同的特点和用途。以下是它们之间的主要区别:顺序表存储方式:在连续的内存空间中存储元素。访问方式:通过索引直接访......
  • 链表-双向链表
    之前实现的是单向链表,即每个节点有一个元素值和一个指向下一个元素的指针,是单向的.head->a->b->c1.现在来做一个双向的,即对每个节点来说,有两个指针,一个链向下一个元素,另一个链向上一个元素.head-><-b-><-c.链表初始化基本的操作套路和单链表是差不多的......