1. 题目
https://leetcode.cn/problems/reorder-list/
考察点
- 这道题的考察点是链表的操作,包括找到链表的中点,反转链表,合并链表等。这些操作都是链表的基本技巧,需要熟练掌握
- 这道题也可以看作是一个数学问题,就是如何把一个序列重新排列成另一个序列,满足一定的规律。这里的规律是把序列分成两部分,然后交替取元素。这种问题可以用递归或者迭代的方法来解决。
- 这道题还可以考察你的编程能力,比如如何写出清晰,高效,可读的代码,如何处理边界情况,如何优化空间和时间复杂度等
2. 解法
解法的思路
- 首先用快慢指针找到链表的中点,把链表分成两部分。
- 然后反转后半部分的链表,这样就可以从两端向中间遍历。
- 最后交替合并两个链表,把后半部分的节点插入到前半部分的节点之间。
代码逻辑
代码的逻辑。代码分为三个步骤:
- 第一步是找到链表的中点,把链表分成两部分。这里用了一个快慢指针的技巧,快指针每次走两步,慢指针每次走一步,当快指针到达链表尾部时,慢指针就是中点。例如,对于链表1->2->3->4->5,快指针会走到5,慢指针会走到3,所以链表可以分成1->2->3和4->5两部分。
- 第二步是反转后半部分的链表,这样就可以从两端向中间遍历。这里用了一个常见的反转链表的方法,用一个prev指针记录前一个节点,一个curr指针记录当前节点,然后不断更新curr.next = prev,prev = curr,curr = curr.next,直到curr为空。例如,对于链表4->5,反转后变成5->4。
- 第三步是交替合并两个链表,把后半部分的节点插入到前半部分的节点之间。这里用了两个指针first和second分别指向两个链表的头节点,然后不断更新first.next = second,first = first.next,second.next = first,second = second.next,直到second.next为空。例如,对于链表1->2->3和5->4,合并后变成1->5->2->4->3。
这样就完成了重新排列链表的任务。
具体实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | public class Solution { public void reorderList(ListNode head) { if (head == null || head.next == null ) return ; // 找到链表的中点 ListNode slow = head, fast = head; while (fast.next != null && fast.next.next != null ) { slow = slow.next; fast = fast.next.next; } // 反转后半部分的链表 ListNode prev = null , curr = slow.next; while (curr != null ) { ListNode next = curr.next; curr.next = prev; prev = curr; curr = next; } // 合并两个链表 ListNode first = head, second = prev; while (second.next != null ) { ListNode next = first.next; first.next = second; first = next; next = second.next; second.next = first; second = next; } } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)