【LeetCodehot100】T24:两两交换链表中的节点 T25:K个一组翻转链表

T24:两两交换链表中的节点

题目核心是:两个两个一组,进行交换。

交换的是节点,不是数字

我们来举例只有两个节点的情况:(1->2)

原来:

1.next=2;

2.next=null

我们要变换为:

2.next=1;

1.next=null;

所以需要三步

  1. 保存2
  2. 让2指向1
  3. 修改1的next

当不止有一组时怎么办?

当:

1 → 2 → 3 → 4

我们发现问题:

第一组交换后,怎么连接后面的节点?

这时就需要用到虚拟头节点dummy

交换一组节点需要几个指针?

以a → b为例:

pre → a → b → next

需要四个。

例如:

dummy → 1 → 2 → 3

这里:

pre = dummy

a = 1

b = 2

next = 3

交换操作(核心)

原来:pre → a → b → next
第一步

pre.next=b;

第二步

a.next=b.next

a后面的b已经更新到per的后面,所以我们更新a.next为b的后面一位,就是b.next

第三步

b.next=a;

然后移动指针

交换完一组后:

pre = a

因为:

a 已经在后面

继续处理下一组。

代码实现

java 复制代码
ListNode dummy=new ListNode(0);
dummmy.next=head;
ListNode pre=dummy;

while(pre.next!=null&&pre.next.next!=null){
//交换
pre.next=b;
a.next=b.next;
b.next=a;

//移动到下一组
pre=a
}
return dummy.next;

T25:K个一组翻转链表

核心理解:

给你:1 → 2 → 3 → 4 → 5

k = 2

要求:

每 k 个节点为一组进行反转。

本质高手:

1 找到一组 k 个节点

2 把这 k 个节点反转

3 接回原链表

整体流程

例如

1 → 2 → 3 → 4 → 5

k = 3

流程:

第一步 找到一组

1 2 3

第二步 断开链表

1 → 2 → 3

后面

4 → 5

第三步 反转

3 → 2 → 1

第四步 接回原链表

3 → 2 → 1 → 4 → 5

第五步 继续下一组

4 5

不够3个

结束。

四、为什么需要 dummy 节点

很多链表题都会写:

ListNode dummy = new ListNode(0);

dummy.next = head;

结构变成

dummy → 1 → 2 → 3 → 4 → 5

作用:

统一处理头节点

因为反转后:

3 会成为新头节点

dummy可以帮我们管理这个变化。

五、关键指针

代码里会用到几个指针:

dummy

pre

end

start

next

作用:

指针 作用
dummy 虚拟头节点
pre 当前组前一个节点
end 当前组最后一个节点
start 当前组第一个节点
next 下一组开始节点

六、完整流程图

原链表

dummy → 1 → 2 → 3 → 4 → 5

第一步 找到 k 个节点

移动 end:

1

2

3

现在

pre → dummy

start → 1

end → 3

第二步 记录下一组

next = 4

第三步 断开链表

end.next = null

现在链表

1 → 2 → 3

第四步 反转链表

调用

reverse(start)

得到

3 → 2 → 1

第五步 接回链表

原来

dummy → 1 → 2 → 3

现在

dummy → 3 → 2 → 1

然后

1 → 4 → 5

最终

dummy → 3 → 2 → 1 → 4 → 5

第六步 移动指针

pre = start

end = pre

继续处理下一组。

代码实现

java 复制代码
class Solution {

    public ListNode reverseKGroup(ListNode head, int k) {

        // 创建虚拟头节点,解决头节点变化的问题
        // 例如反转后新的头节点可能不是原来的 head
        ListNode dummy = new ListNode(0);
        dummy.next = head;

        // pre:每一组反转前的那个节点
        ListNode pre = dummy;

        // end:用于寻找当前这一组的第 k 个节点
        ListNode end = dummy;

        while(true){

            // 1. 找到当前这一组的第 k 个节点
            // end 向前走 k 步
            for(int i = 0; i < k && end != null; i++){
                end = end.next;
            }

            // 如果不够 k 个节点,直接结束
            if(end == null){
                break;
            }

            // 2. 记录当前这一组的开始节点
            // pre -> start -> ... -> end
            ListNode start = pre.next;

            // 3. 记录下一组开始的位置
            // end -> next
            ListNode next = end.next;

            // 4. 断开当前这一组链表
            // 例如:
            // 1 → 2 → 3 → 4 → 5
            // 变成
            // 1 → 2 → 3 → null    4 → 5
            end.next = null;

            // 5. 反转当前这一组链表
            // reverse(start) 返回新的头节点
            // 例如 1→2→3 变成 3→2→1
            pre.next = reverse(start);

            // 6. 把反转后的链表接回去
            // start 此时已经变成这一组的最后一个节点
            // 让它指向下一组
            start.next = next;

            // 7. 移动指针,为下一组做准备
            // pre 移动到这一组的最后一个节点
            pre = start;

            // end 重新回到 pre 的位置
            end = pre;
        }

        // 返回新的头节点
        return dummy.next;
    }


    // 反转链表函数
    private ListNode reverse(ListNode head){

        // pre:反转后的链表头
        ListNode pre = null;

        // cur:当前正在处理的节点
        ListNode cur = head;

        while(cur != null){

            // 保存下一个节点
            ListNode next = cur.next;

            // 反转指针
            // 例如:2 → 1
            cur.next = pre;

            // pre 前进一步
            pre = cur;

            // cur 前进一步
            cur = next;
        }

        // 返回反转后的头节点
        return pre;
    }
}
相关推荐
Chester_19993 小时前
CSP202203C.计算资源调度器
开发语言·数据结构·c++·蓝桥杯
裕晟资质规划4 小时前
武器装备科研生产单位保密资质申请方法论:条件模型与流程拆解
人工智能·算法
EXI-小洲4 小时前
Java 操作 Word:字符串替换、图片插入、动态生成表格与API接口下载
java·开发语言·spring boot·word
2601_961901705 小时前
SpringBoot使用Nacos进行application.yml配置管理
java·spring boot·spring
en.en..5 小时前
C语言 标准输入 / 输出缓冲区
算法
STQY燊桐启元(深圳)电子科技6 小时前
医疗精密电源散热方案:相变陶瓷片保障医疗设备长效稳定低干扰
大数据·网络·人工智能
何以解忧,唯有..6 小时前
LangChain 工具调用(Tool Calling)实战指南
java·前端·langchain
QQ_21696290966 小时前
【源码编号:project79475】SpringBoot校内二手交易平台:商品发布、分类检索、留言交流、订单管理全流程实战
java·spring boot·后端
吃好睡好便好7 小时前
查找函数的使用
学习·算法·matlab·生活·查找函数
学习星球7 小时前
单调栈——从“找下一个更大的“到柱状图中的最大矩形
数据库·c++·算法·leetcode·xcode