力扣链表高频题:两两交换节点 + K个一组翻转链表(保姆级思路+满分代码)

链表翻转、节点交换是力扣的高频必考题型 ,也是面试手撕链表的常客。今天一次性攻克两道经典题:24. 两两交换链表中的节点25. K 个一组翻转链表,从思路拆解到代码实现,一步步讲透,新手也能轻松拿捏。

这两道题一脉相承,两两交换其实就是K=2的特殊情况,掌握通用解法,两道题一起搞定,高效刷题不费力~

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

题目大意

给定一个链表,两两交换相邻的节点,返回交换后的链表头节点,要求不能单纯修改节点的值,必须真正执行节点交换操作。

解题思路

这道题直接操作节点指针即可,核心是借助虚拟头节点统一链表头节点和后续节点的处理逻辑,避免单独处理头节点的边界情况。

解题时定义四个辅助节点,分步完成交换:

  1. 虚拟节点:作为链表的前驱节点,解决头节点交换后丢失的问题
  2. 临时指针:始终指向待交换两个节点的前一个节点,用于衔接交换后的节点
  3. first、second:分别指向当前要交换的第一个和第二个节点
  4. tmp:保存待交换节点的后继节点,防止交换后链表断裂

循环判断条件:保证后续有两个节点可以交换,再执行交换逻辑,不足两个节点直接终止循环。

满分代码

复制代码
/**
 * 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) {
        // 定义虚拟头节点,统一链表操作逻辑
        ListNode current = new ListNode(-1);
        current.next = head;

        // 临时节点,始终指向待交换节点的前一个位置
        ListNode cu = current;
        // 声明待交换的两个节点,以及后继节点
        ListNode first;
        ListNode second;
        ListNode tmp;
        
        // 后续有两个节点,才执行交换
        while (cu.next != null && cu.next.next != null) {
            // 定位两个待交换节点
            first = cu.next;
            second = cu.next.next;
            // 保存后继节点,防止链表断裂
            tmp = cu.next.next.next;
            
            // 执行节点交换
            cu.next = second;
            second.next = first;
            first.next = tmp;
            
            // 指针后移,准备下一轮交换
            cu = first;
        }
        // 返回新的链表头
        return current.next;
    }
}

25. K 个一组翻转链表 - 力扣(LeetCode)

题目大意

给你链表的头节点 head,每 k 个节点一组进行翻转,返回修改后的链表。k 是正整数,它的值小于或等于链表的长度;如果节点总数不足 k 个,保持原有节点顺序不变,同样要求只能操作节点指针,不可修改节点值。

解题思路

这道题是上一题的进阶版,也是链表分组翻转的通用解法,两两交换本质就是k=2的特例,掌握这道题的思路,同类题都能迎刃而解。

  1. 虚拟头节点:依旧用dummy节点,让链表第一个分组的处理逻辑和其他分组完全一致,省去边界判断
  2. 双指针定位:用pre和end两个指针配合工作
    1. pre:始终指向待翻转组的前一个节点,负责衔接翻转后的链表
    2. end:先向前走k步,定位到当前组的最后一个节点,判断剩余节点是否足够k个
  1. 不足k个节点:直接终止循环,保留剩余节点原样
  2. 局部翻转:先断开当前分组与后续链表的连接,单独翻转该组,再将翻转后的分组重新接回原链表
  3. 指针复位:更新pre和end指针,准备下一组的翻转操作

满分代码

复制代码
/**
 * 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 reverseKGroup(ListNode head, int k) {
        // 虚拟头节点,统一链表操作
        ListNode dump = new ListNode(-1);
        dump.next = head;
        // pre:待翻转组的前驱节点,end:当前组的尾节点
        ListNode pre = dump;
        ListNode end = dump;

        while (end.next != null) {
            // 向前走k步,定位到当前组的末尾
            for (int i = 0; i < k && end != null; i++) {
                end = end.next;
            }
            // 剩余节点不足k个,直接退出,保持原样
            if (end == null) break;

            // 记录当前组的起始节点,以及下一组的起始节点
            ListNode start = pre.next;
            ListNode next = end.next;
            // 断开分组,方便单独翻转
            end.next = null;
            // 翻转当前分组
            reverse(start);

            // 将翻转后的分组拼接回原链表
            pre.next = end;
            start.next = next;

            // 指针复位,准备下一组翻转
            pre = start;
            end = start;
        }
        return dump.next;
    }

    // 单链表翻转的工具方法
    public void reverse(ListNode head) {
        ListNode pre = null;
        ListNode cur = head;
        while (cur != null) {
            ListNode tmp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = tmp;
        }
    }
}

刷题总结

这两道链表题核心都是指针操作+虚拟头节点,巧用虚拟节点能规避大量边界问题,写代码更省心。

  • 两两交换:固定分组大小为2,直接交换相邻节点,适合入门练手
  • K个一组翻转:通用分组翻转解法,先定位再翻转,最后衔接链表,适用性更强

链表题切记不要慌,画好节点指针走向,一步步拆解逻辑,手撕代码完全没难度~

相关推荐
Boop_wu2 小时前
[Java 算法] 动态规划2
算法·leetcode·动态规划
yugi9878382 小时前
非支配排序遗传算法NSGA-III详解与MATLAB实现
算法
ballball~~2 小时前
ISP-Tone Mapping
图像处理·算法·isp
米粒12 小时前
力扣算法刷题 Day22
算法·leetcode·职场和发展
科德航空的张先生2 小时前
飞行错觉(空间定向障碍)地面模拟训练系统
人工智能·算法
老四啊laosi2 小时前
[双指针] 2. 力扣--复写零
算法·leetcode·双指针·复写零
ballball~~2 小时前
ISP-Gamma
图像处理·算法·isp
机器学习之心2 小时前
HHO-LSBoost哈里斯鹰算法优化最小二乘提升多输入回归预测MATLAB代码
算法·matlab·回归·hho-lsboost
ballball~~2 小时前
ISP-Demosaic
图像处理·数码相机·算法