代码随想录算法训练营第四天 _ 链表_24. 两两交换链表中的节点、19.删除链表的倒数第N个节点、142.环形链表II 。面试题 02.07. 链表相交

学习目标:

60天训练营打卡计划!

学习内容:

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

  • 如何保留虚拟头节点用于最后的输出?给原链表设置一个虚拟头节点,并保留其身份。
  • 使用了双指针法!
  • 如何确定结束的条件?
    while(cur != null && cur.next != null):
    其中的cur和 cur.next(tmp1)就是要交换的两个节点,所以最后移动的时候pre赋值为cur,而cur的赋值为tmp2。
  • 本题中pre节点是维持要交换的节点前的顺序(因此虚拟头节点得以保留),而tmp2是维持要交换的节点后的顺序。
lass Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode vir = new ListNode(-1,head);
        ListNode pre = vir;
        ListNode tmp1 = null;
        ListNode tmp2 = null;
        ListNode cur = vir.next;
        // cur不为null是约束偶数节点,
        // cur.next != null是为了约束奇数节点
        while(cur != null && cur.next != null){
            // 保存好cur的下一个和下下一个节点信息。
            tmp1 = cur.next;
            tmp2 = cur.next.next;

            // 进行反转操作
            pre.next = tmp1;
            tmp1.next = cur;
            cur.next = tmp2;
            
            // 使pre和cur节点移动
            // 在移动后cur已经成为tmp2的前一位了
            pre = cur;
            cur = tmp2;
        }
        return vir.next;
    }
}

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

  • 是我们熟悉的双指针法!
  • 使用带虚拟头节点的链表来处理,保证对于头节点和其他节点之间的处理规则完全相同。
  • 如何确定快慢指针的间距?距离为N + 1。当慢指针在虚拟节点时,快指针指向链表的第N个数。
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode vir = new ListNode(-1,head);
        ListNode pre = vir;
        ListNode cur = head;

        while( n-- > 0)
            cur = cur.next;

        while(cur != null){
            cur = cur.next;
            pre = pre.next;
        }
        pre.next = pre.next.next;

        return vir.next;
    }
}
  • 从本题,我还学会了:
  • 区别什么是链表的节点的递增:cur = cur.next;什么是节点删除:pre.next = pre.next.next;

142.环形链表II

  • 第一遍实现时逻辑写错了,第一个结束的条件写成快慢指针不相遇,特别长的链表是无法处理的。另一方面是:快慢指针相遇后才找具体的节点,写成
错误逻辑!!!
while(fast != slow){
    fast = fast.next.next;
    slow = slow.next;
}
while(tmp != slow){
     tmp = tmp.next;
     slow = slow.next;
}

理论分析:假设快指针每次走两个节点,慢指针每次走一个节点,所以快指针相对于慢指针的速度是1个节点。
请添加图片描述

真实的逻辑应该是先循环判定是不是空?不是空才去找递增快慢指针,然后如果相遇,才会找具体的节点。

public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        while(fast != null && fast.next != null && fast.next.next != null){
            fast =fast.next.next;
            slow = slow.next;
            // 快慢节点相遇
            if(slow == fast){
                ListNode tmp = head;
                // 查找链表和环的交界
                while(tmp != slow){
                    tmp = tmp.next;
                    slow = slow.next;
                }
                return tmp;
            }
        }
        return null;
    }
}

学习时间:

  • 看视频一小时,下午两小时,整理文档半小时
  • 12月7日复习,142不熟悉。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值