代码随想录算法训练营day04 | 24. 两两交换链表中的节点 , 19.删除链表的倒数第N个节点 ,面试题 02.07. 链表相交 ,142.环形链表II


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

教程视频:https://www.bilibili.com/video/BV1YT411g7br/?vd_source=ddffd51aa532d23e6feac69924e20891添加链接描述
在这里插入图片描述在这里插入图片描述

解法一

注意这里是交换链表节点,而不是交换链表节点中的值

    public ListNode swapPairs(ListNode head) {
        ListNode cur = new ListNode(0);
        ListNode dummyHead = new ListNode(0);
        dummyHead.next = head;
        cur = dummyHead;

        while(cur.next!=null && cur.next.next!=null){
            ListNode tempNode = cur.next;
            ListNode tempNode1 = cur.next.next.next;
            cur.next = cur.next.next;
            cur.next.next = tempNode;
            tempNode.next = tempNode1;
            cur = cur.next.next;
        }
        return dummyHead.next;
    }

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

教程视频:
截图
在这里插入图片描述

解法一:虚拟头节点+快慢指针

    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dumHead = new ListNode();
        dumHead.next = head;
        ListNode cur = dumHead;
        ListNode slow = dumHead;
        while(n!=0){
            cur = cur.next;
            n--;
        }
        while(cur.next!=null){
            slow = slow.next;
            cur = cur.next;
        }

        //此时 dumHead 为倒数n+1个结点
        slow.next = slow.next.next;
        return dumHead.next;
    }

面试题 02.07. 链表相交

教程视频:
截图

解法一:链表右对齐

这题要抓住相交后节点后的链表长度一致,因此要先将两链表后对齐,之后再进行比对.
同时,本题不需要修改链表元素,所以不使用虚拟头节点.

    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
    	// 求两链表的长度
        ListNode curA = headA;
        int lenA = 0;
        while(curA!=null){
            lenA++;
            curA = curA.next;
        }
        ListNode curB = headB;
        int lenB = 0;
        while(curB!=null){
            lenB++;
            curB = curB.next;
        }
        curA = headA;
        curB = headB;

        //让链表B为长链表的头,lenB是其长度
        if(lenA>lenB){
            ListNode temp = curA;
            curA = curB;
            curB = temp;
            int tempLen = lenA;
            lenA = lenB;
            lenB = tempLen;
        }

        //求节点数差值
        int gap = lenB - lenA;

        while(gap!=0){
            curB = curB.next;
            gap--;
        }

        //此时,从 curA curB开始的节点数值相等
        while(curA!=null){
            if(curA == curB){
                return curA;
            }
            curA = curA.next;
            curB = curB.next;
        }
        return curA;
    }

142.环形链表II

教程视频:
截图
在这里插入图片描述

解法一:环形链表操作(快慢指针判断环+找环入口)

环形链表主要考察两个点:
1.如何判断环形存在

  • 注意环形链表不能遍历,否则会陷入死循环.
  • 判断环存在要使用快慢指针,分别定义 fast 和 slow 指针,从头结点出发,fast指针每次移动两个节点,slow指针每次移动一个节点,如果 fast 和 slow指针在途中相遇,说明这个链表有环。

2.如何寻找环入口
确定有环时,快慢指针在环中相遇.
图源:代码随想录经推理可知:x = (n - 1) (y + z) + z
( 详细推理过程见:https://programmercarl.com/0142.%E7%8E%AF%E5%BD%A2%E9%93%BE%E8%A1%A8II.html )
上式说明, 从相遇点和头节点以相同速度移动,相遇的地方就是环形入口的节点。

    public ListNode detectCycle(ListNode head) {
        //定义快慢指针
        ListNode fast = new ListNode();
        ListNode slow = new ListNode();
        fast.next = head;
        slow.next = head;

        //判断是否有环
        while(fast!=null && fast.next!=null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast==slow){
                //记录相遇的位置
                ListNode index2 = fast;
                ListNode index1 = new ListNode();
                index1.next = head;
                //寻找环入口
                while(index1!=index2){
                    index1 = index1.next;
                    index2 = index2.next;
                }
                return index1;
            }
        }
        //没环则输出null
        return null;
        
    }

总结

1.使用虚拟头节点时,返回节点使用虚拟头节点表示,而不使用题干给出的head表示;
2.与链表倒数n元素相关的题可用快慢指针处理;
3.相交元素要抓住相交后链表长度一致;
4.环形链表不能遍历,需要用快慢指针来确定环存在以及寻找环入口.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值