鱼C论坛

 找回密码
 立即注册
查看: 98|回复: 3

k个一组翻转链表(堆栈解决)

[复制链接]
发表于 2024-10-16 15:22:53 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
class Solution:
    def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
        h = t = ListNode(0, head)
        p, stack = head, []        
        while True:
            for _ in range(k):
                if p: 
                    stack.append(p)     # 压栈
                    p = p.next
                else: return h.next     # 不满栈,直接返回
            for _ in range(k):
                t.next = stack.pop()    # 出栈,同时续到链表尾部
                t = t.next
            t.next = p                  # 连接后段链表
帮我解读一下上述使用堆栈思想的代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-10-16 15:44:01 | 显示全部楼层
这段代码实现了将链表按每组 `k` 个节点进行翻转的操作,采用了堆栈(栈)的思想来实现。现分解其关键逻辑:

1. **初始化**:
   - `h` 和 `t`:创建哑节点(dummy node),`h` 用来返回结果链表的头,`t` 用来持有链表尾部的指针。
   - `p`:指向当前处理的节点的指针,初始为 `head`。
   - `stack`:用于临时存储每组 `k` 个节点的栈。

2. **开始翻转过程**:
   - 外层是一个无限循环,因为我们不知道总共有多少组 `k` 个节点。
   - **压栈**:内层 `for` 循环用于将 `k` 个节点压入 `stack` 中。如果在压栈过程中 `p` 变为 `None`(链表节点不足 `k` 个),则直接返回从哑节点 `h` 开始的链表。

3. **出栈并连接**:
   - 另一个内层 `for` 循环弹出 `k` 个节点并逐个连接到链表尾部。
   - 弹出的节点 `t.next` 被赋值为 `stack.pop()`,并且指针 `t` 向后移动。

4. **连接后段链表**:
   - `t.next = p` 这一步将当前翻转后的尾节点 `t` 连接到剩下的未处理的链表部分,确保链表的完整性。

整个过程会持续到无法再压入 `k` 个节点,这时说明翻转结束。

总的来说,这段代码巧妙利用堆栈实现每 `k` 个节点的翻转,以一种清晰且简单的思路处理链表翻转问题,是一个经典的使用堆栈进行链表操作的例子。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-10-16 17:40:29 | 显示全部楼层
FishC 发表于 2024-10-16 15:44
这段代码实现了将链表按每组 `k` 个节点进行翻转的操作,采用了堆栈(栈)的思想来实现。现分解其关键逻辑 ...

class Solution:
    def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
        #运用栈(堆栈)的后进先出思想
        h = ListNode(0,head) #原始链表设置哨兵变量
        t = ListNode(0,head) #新链表设置哨兵变量
        p = head #头结点赋值给p指针
        st = []
        while True:
            for _ in range(k): #需翻转的元素入栈
                if p:
                    st.append(p)
                    p = p.next
                else:
                    return h.next #链表结点个数小于k,不翻转,直接返回剩余结点
            for _ in range(k): #需翻转的元素出栈
                t.next = st.pop()
                t = t.next
            t.next = p
我的代码这样写结果不对,哪里有问题
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-10-16 17:40:45 | 显示全部楼层
Terence888 发表于 2024-10-16 17:40
class Solution:
    def reverseKGroup(self, head: ...


在您的代码中,出现了几个问题与疏忽需要处理:

1. **栈 `st` 未初始化**:
   - 需要在使用栈 `st` 之前将其初始化为空列表,如 `st = []`。

2. **哨兵节点 `t` 的初始化问题**:
   - 您初始化 `t` 为新建的哨兵节点,但没有和 `h` 关联。实际上,`t` 应该引用 `h`,即 `t = h`,以保持新建链表的连接一致性。

3. **代码格式问题**:
   - 您可能的代码复制过程中,存在一些特殊的无效字符和不正确缩进(如多余空格)。请确保代码格式正确。

以下是修正后的代码片段:
class Solution:
    def reverseKGroup(self, head: Optional, k: int) -> Optional:
        h = t = ListNode(0, head)  # 使用同一哨兵初始化 `h` 和 `t`
        p = head  # 初始化迭代指针
        st = []  # 初始化栈

        while True:
            for _ in range(k):  # 将当前k个元素压入栈中
                if p:
                    st.append(p)
                    p = p.next
                else:
                    return h.next  # 如果节点不足k个,返回哨兵的下一个节点,即处理后的链表
            
            for _ in range(k):  # 从栈中弹出元素实现翻转
                t.next = st.pop()
                t = t.next
            
            t.next = p  # 连接剩余未翻转的部分

请确保代码中的缩进正确,`st` 被初始化为列表,并且记录新链表的 `t` 应与 `h` 一起在同一哨兵节点上初始化,以便正确串接翻转的链表。这样可以确保 `reverseKGroup` 的逻辑实现是正确的。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-22 17:22

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表