刷题日记 Day 4 :两两交换链表中的节点、删除链表的倒数第 N 个节点、链表相交、环形链表 II

本篇文章 , 是在代码随想录 60 天编程挑战的基础上进行的题目讲解
参与链接在此 : https://programmercarl.com/other/xunlianying.html

大家好 , 这个专栏 , 给大家带来的是 60 天刷题强训 . 最令大家头疼的事就是刷题了 , 题目又臭又长又抽象 , 有的题读都读不懂 , 更别说做了 . 所以 , 这个专栏想要帮助大家摆脱困境 , 横扫饥饿 , 做回自己 . 让大家掌握最常见的面试题 , 面对陌生的题目也不至于无从下手 .
也希望大家监督 , 60 天从 0 到 1 , 咱们一起做大佬 ~
今天是 Day4 , 大家加油~
image.png
专栏链接 : https://blog.csdn.net/m0_53117341/category_12247938.html?spm=1001.2014.3001.5482
昨天的打卡链接 : http://t.csdn.cn/zNysy

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

题目链接 : 24. 两两交换链表中的节点
image.png
其实对于链表的很多问题 , 不是那么麻烦 .
但是必须大家对这道题有清晰的思路 , 才能完美实现
那么给大家介绍一下这道题的思路
image.png
如果理顺了思路 , 代码一点都不难实现
代码给大家贴在这里了

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    
    
    public ListNode swapPairs(ListNode head) {
    
    
        // 1. 定义虚拟头节点
        ListNode tmpHead = new ListNode(-1);
        tmpHead.next = head;

        // 2. 定义 cur 指针,让他先指向虚拟头结点
        ListNode cur = tmpHead;

        // 3. 循环交换链表节点
        while(cur.next != null && cur.next.next != null) {
    
    
            // 先将这组第一个节点保存起来,要不然后面找不到
            ListNode tmp1 = cur.next;
            // 再将下一组链表的第一个节点保存起来,省的也找不到
            ListNode tmp2 = cur.next.next.next;
            // 进行交换
            cur.next = cur.next.next;
            cur.next.next = tmp1;
            tmp1.next = tmp2;

            // 要将 cur 移动到这组最后一个元素
            cur = cur.next.next;
        }

        return tmpHead.next;
    }
}

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

题目链接 : 19. 删除链表的倒数第 N 个结点
image.png
这道题 , 还是清楚了思路之后不难实现
我们就给大家介绍一下这道题的思路
image.png

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    
    
    public ListNode removeNthFromEnd(ListNode head, int n) {
    
    
        // 1. 定义虚拟头节点
        ListNode tmpHead = new ListNode(-1);
        tmpHead.next = head;

        // 2. 定义快慢指针
        ListNode fast = tmpHead;
        ListNode slow = tmpHead;

        // 3. 先让 fast 走 n+1 步
        int tmp = n + 1;
        // 注意判断 fast 指针走没走到空
        // 比如:1 2 3 4 5 , 找倒数第 100 个节点,fast 走到 100 肯定是空指针了
        while(tmp-- != 0 && fast != null) {
    
    
            fast = fast.next;
        }

        // 4. 接下来 fast slow 一起走
        // fast 走到空的时候,slow就到了倒数第 k 个节点的前面
        while(fast != null) {
    
    
            fast = fast.next;
            slow = slow.next;
        }

        // 5. 跳过倒数第 k 个节点
        slow.next = slow.next.next;

        return tmpHead.next;
    }
}

三 . 面试题 02.07. 链表相交

题目链接 : 面试题 02.07. 链表相交
image.png
这道题 , 也是标准的知道解法 , 题目就非常 easy 的一道题
大家来看一下解法~
image.png

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    
    
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
    
    
        // 1. 定义两条指针,分别指向 headA,headB
        ListNode cur1 = headA;
        ListNode cur2 = headB;

        // 2. 让 cur1 cur2 一直往后走
        while(cur1 != cur2) {
    
    
            // 当 cur1 走到空的时候,让他指向 headB
            if(cur1 == null) {
    
    
                cur1 = headB;
            } else {
    
     // 否则正常往后走就行
                cur1 = cur1.next;
            }

            // 当 cur2 走到空的时候,让他指向 headA
            if(cur2 == null) {
    
    
                cur2 = headA;
            } else {
    
     // 否则正常往后移动
                cur2 = cur2.next;
            }
        }

        // 3. 这时候,cur1 cur2 相遇,返回其中任意一个即可
        return cur1;
    }
}

四 . Leetcode 142 . 环形链表 II

题目链接 : 142. 环形链表 II
image.png
实际上这道题 , 是两道题
它的前身是判断链表是否有环 141. 环形链表
那我们就这两道题都看了
image.png
我们这里只实现环形链表 II 这道题 , 因为这道题会了 , 那环形链表 I 也没问题~

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    
    
    public ListNode detectCycle(ListNode head) {
    
    
        // 1. 定义快慢指针
        ListNode fast = head;
        ListNode slow = head;

        // 2. 让快慢指针移动,相遇就代表链表有环
        // 循环条件:因为 fast 一直走在 slow 前面,所以只需要判断 fast 的条件即可
        while(fast != null && fast.next != null) {
    
    
            // 快指针每次走两步,慢指针每次走一步
            fast = fast.next.next;
            slow = slow.next;

            // 相遇的时候,在相遇点处创建一个 index1 指针,在起点创建一个 index2 指针
            // 相遇的时候就是入口节点
            if(fast == slow) {
    
    
                ListNode index1 = fast;
                ListNode index2 = head;

                // index1 index2 各自移动
                while(index1 != index2) {
    
    
                    index1 = index1.next;
                    index2 = index2.next;
                }

                // 这时候,index1 index2 相遇了,返回其中一个即可
                return index1;
            }
        }

        // 整个 while 循环走完了还没找到 -> 返回 null
        return null;
    }
}

今天的任务就完成啦~
没白活一天~
如果对你有帮助的话 , 请一键三连嗷~
image.png

猜你喜欢

转载自blog.csdn.net/m0_53117341/article/details/129660866