lc hot 100之:dummy哨兵节点创建方法
嗨嗨嗨大家好!今天又写了一题链表,发现自己不会创建dummmy哨兵节点qvq(应该是c语言语法忘光光了哈哈哈哈哈哈)所以求助了一下ai整理了两种哨兵节点的创建方法~
题目的思路并不难但也很巧妙,
首先我们想肯定要找到最后一个节点往前遍历才能找到倒数第n个节点,对吧?
再想想【双指针】呢?如果有两个指针left和right,right一开始就比left快n个位置,那么是不是right到末尾时,left正好是倒数第n个?
这样只需要遍历一次就好啦!
删除节点需要找到该节点的前一个节点,此外我们还要考虑删完后链表为空的情况。
因此,提前加入dummy哨兵节点就可以完美解决这两个问题!(保证删完后链表不为空是哨兵节点的重要应用)
代码:
class Solution {
public:ListNode* removeNthFromEnd(ListNode* head, int n) {// 由于可能会删除链表头部,用哨兵节点简化代码// ListNode dummy{0, head};ListNode *dummy=new ListNode(0,head);ListNode *left=dummy, *right=dummy;while(n--){right=right->next;//right后移n个,这样1right到末尾时left正好是第n个}while(right->next){right=right->next;left=left->next;}left->next=left->next->next;return dummy->next;}
};
接下来详细介绍dummy的两种创建方法!
第一种:动态分配哨兵节点
ListNode *dummy=new ListNode(0,head);
ListNode *left=dummy, *right=dummy;
- 原理:使用
new
在堆上分配内存 - 生命周期:手动控制,必须delete显式释放(题目中可能不需要)
第二种: 栈分配哨兵节点
ListNode dummy{0, head};
ListNode *left=&dummy, *right=&dummy;
- 原理:在函数栈帧中创建局部变量
- 生命周期:函数执行期间存在,函数返回时自动释放
注意:
dummy
是一个ListNode
类型的对象left
是一个ListNode*
类型的指针- &dummy 获取 dummy 的内存地址
一定要注意和上一种方法不一样的地方!!!!!!
重新给出代码:
class Solution {
public:ListNode* removeNthFromEnd(ListNode* head, int n) {// 由于可能会删除链表头部,用哨兵节点简化代码ListNode dummy{0, head};// ListNode *dummy=new ListNode(0,head);// ListNode *left=dummy, *right=dummy;ListNode *left=&dummy, *right=&dummy;while(n--){right=right->next;//right后移n个,这样1right到末尾时left正好是第n个}while(right->next){right=right->next;left=left->next;}left->next=left->next->next;return dummy.next;}
};
并且,还有一处不一样的地方
如果创建的dummy是实际对象(第二种方法),那么return dummy.next;
如果创建的dummy是ListNode*
类型的指针(第一种方法),那么return dummy->next;
完结撒花!希望下次能自己写出来dummy的创建!耶又弄明白了一个知识点!