链表——删除链表的倒数第N个节点 && 链表相交

记录一下代码随想录,19.删除链表的倒数第N个节点面试题02.07.链表相交 两个题。

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

进阶:你能尝试使用一趟扫描实现吗?

这题涉及到删除头节点,为了方便就采用虚拟头节点来做(基本上都是用虚拟头节点,从而节省对头节点的额外处理)。

想到一趟扫描,就想到了双指针。这里使用一快一慢两个指针:fast、slow。

可以推导,让fast 指针先移动N个节点,之后让fast 和 slow同时移动,直至fast 指向链表尾端的null,那么,此时slow 指向的节点就是倒数第N个节点(要被删除的节点)

因为删除节点需要依靠该节点的前一个节点,所以实际会让fast 指针先移动 N+1 个节点。此时,fast 循环结束后,slow 的下一个节点就是倒数第N个节点。

代码如下:

ListNode dummyHead = new ListNode(-1, head);
ListNode fast = dummyHead;
ListNode slow = dummyHead;

while (n-- > 0) {
    fast = fast.next;
}
fast = fast.next;            // 移动N+1 个节点

while (fast != null) {       // 循环
    fast = fast.next;
    slow = slow.next;
}
slow.next = slow.next.next;  // 删除倒数第N个节点

return dummyHead.next;

 ——————————————————————————————————————————

链表相交

这个题是一个简单题,只需要注意 链表如果有相交,那么他们必定是从某个节点开始一直到尾部节点都一样,相交的节点必定是在短链表中

接下来只需要模拟就可以了。

先让两个链表尾端对齐。假设长链表长度为 lenA,短链表长度为 lenB。尾端对齐,即让长链表指针向后移动 lenA-lenB 个节点。

然后就是一一比对节点,直至找到一个相交的节点,或者 null。

 代码如下:

ListNode curA = headA;
ListNode curB = headB;
int lenA = 0;
int lenB = 0;

while (curA != null) {    // 获取链表A的长度
    curA = curA.next;
    lenA++;
}
while (curB != null) {    // 获取链表B的长度
    curB = curB.next;
    lenB++;
}

curA = headA;
curB = headB;
if (lenB > lenA) {        
    int len = lenB;       // 让 lenA 代表长链表的长度,lenB 代表短链表的长度
    lenB = lenA;
    lenA = len;
    ListNode temp = curB; // 让 curA 指向长链表的头节点,lenB 指向短链表的头节点
    curB = curA;
    curA = temp;
}

int n = lenA - lenB;
while (n-- > 0) {         // 让两个链表的尾端对齐
    curA = curA.next;
}

while (curA != null) {    // 寻找相交的节点
    if (curA == curB)
        return curA;
    curA = curA.next;
    curB = curB.next;
}

return null;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值