算法训练营day4

两两交换链表中的节点

两种解法都很值得学习,第二种解法可以增强对dummy节点的理解

参考链接24. 两两交换链表中的节点 - 力扣(LeetCode)

方法一,递归
class Solution {
    public ListNode swapPairs(ListNode head) {
        if(head == null || head.next == null){
            return head;
        }
        ListNode next = head.next;
        //以两个节点为单位分割,例如 3 4 1 2 ,此时 head = 3, next = 4
        //再调用 swapPairs(next.next) 让 1 和 2 进行调换
        //因为 3 4 调换成 4 3 那么此时 head.next(3.next) 正好连接后面的子单元
        head.next = swapPairs(next.next);
        // 4.next 连接 3完成调换
        next.next = head;
        return next;
    }
}
方法二,设置虚拟头指针操作
  1. 通过day03和该解法 总结小规律,在对链表进行对换(修改位置)操作时(pre,cur,next)
  2. 通常先将pre节点与next节点连接(pre.next = next) & 并保存好next.next(start.next = next.next)之后,再更改cur节点(这道题pre -> temp/ cur -> start/ next -> end)
class Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode pre = new ListNode(0);
        pre.next = head;
        ListNode temp = pre;
        while(temp.next != null && temp.next.next != null) {
            ListNode start = temp.next;
            ListNode end = temp.next.next;
            temp.next = end;
            start.next = end.next;
            end.next = start;
            temp = start;
        }
        return pre.next;
    }
}

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

  1. 保存dummy结点,始终指向head
  2. 通过双指针相差n个索引,快指针先移动n位,然后同时移动快指针和慢指针,当快指针达到末尾时,慢指针刚好和快指针差n位
  3. 注意:此时慢指针所在的位置是倒数第n位的前一位
    • 例;… 3 4 5 6,要删除倒数第2位,那么 6 -> 5 -> 4 ,当前慢指针所在的位置是4,是倒数第三位
  4. 根据链表删除的原理 slow.next = slow.next.next即可

02.07链表相交

  1. 假设ab链表相交,那么它们的末尾距离相交位置的长度是相同的,设为C
  2. 那么a -> 链表末尾 -> b头部 -> 相交点 行走的距离是 a + b - c
  3. b运行同理
  4. 遍历速度相同,行走距离相同,如果ab相交最后会在相交点相遇即 pA = pB
  5. 如果不相交最后都会遍历到末尾 即 null == null也可结束循环

环形链表二

思路见注释

public class Solution {
    public ListNode detectCycle(ListNode head) {
        //快慢指针 fast = 2 * slow,设环的长度为c,fast走2s,slow走s,头部到环入口的距离为a,相遇时fast比slow多走n圈
        //相遇时 s = a + xb  2s = a + (x+n)b   2a + 2xb = a + (x+n)b -> a + xb - nb = 0 -> s = nb,
        // 也就是说slow走的路程,和fast多走的路程相同,那么将fast重置到头结点并将其速度变为1,两个指针再继续运动
        //当"fast"到达 环入口时,"slow"走的路程为 nb + a 也刚好在入口,那么此时两个指针指向的就是环的入口
        ListNode fast = head, slow = head;
        while(true){
            if(fast == null || fast.next == null) return null;
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow) break;
        }
        fast = head;
        while(slow != fast){
            slow = slow.next;
            fast = fast.next;
        }
        return fast;
    }
}
  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值