题目描述:
给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。
思路分析:
没到指定的位置范围时,直接进行链表的链接,然后到了需要转换的范围就将这些节点用一个栈保存,然后再利用栈的先入后出进行节点的链接,最后将剩下的节点进行链接即可。注意代码的逻辑,如果在一个for中进行所有操作可能导致逻辑的混乱,所以最好将各个功能分开实现。用不同的for实现即可,题目给定的left和right可以成为一个分界值,可以之间利用。 但是这样做会利用额外的空间,空间复杂度较高,所以还有一种原地交换的方法。[头插法]
点击查看代码
func reverseBetween(head *ListNode, left int, right int) *ListNode { if head == nil || left == right { return head } // 创建 dummy 节点来处理边界情况 dummy := &ListNode{Next: head} pre := dummy // 1. 定位到 `left` 前一个节点 for i := 1; i < left; i++ { pre = pre.Next } // 2. 使用栈保存 `left` 到 `right` 范围的节点 var stack []*ListNode cur := pre.Next for i := left; i <= right; i++ { stack = append(stack, cur) cur = cur.Next } // 3. 出栈并反转连接节点 for len(stack) > 0 { pre.Next = stack[len(stack)-1] // 连接出栈的节点 stack = stack[:len(stack)-1] // 出栈 pre = pre.Next // 移动 pre 指针 } // 4. 连接剩余的部分 pre.Next = cur return dummy.Next }
头插法原地交换
找到第一个需要反转的结点的前一个结点 p,从这个结点开始,依次把后面的结点用“头插”法,插入到 p 结点的后面。循环次数用 n-m 来控制。 重点查看最后一个for循环实现的头插法的代码。
点击查看代码
func reverseBetween(head *ListNode, left int, right int) *ListNode { if head == nil || left == right { return head } // 创建 dummy 节点,帮助处理头节点的边界情况 dummy := &ListNode{Next: head} pre := dummy // 将 pre 移动到 left 前一个节点的位置 for i := 1; i < left; i++ { pre = pre.Next } // 开始反转的位置 cur := pre.Next var next *ListNode // 反转指定区域的节点 for i := 0; i < right-left; i++ { next = cur.Next cur.Next = next.Next next.Next = pre.Next pre.Next = next } return dummy.Next }
合集:
链表
分类:
Go刷Leetcode
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 为DeepSeek添加本地知识库
· 精选4款基于.NET开源、功能强大的通讯调试工具
· DeepSeek智能编程
· 大模型工具KTransformer的安装
· [计算机/硬件/GPU] 显卡