lotus

贵有恒何必三更眠五更起 最无益只怕一日曝十日寒

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

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。

这样就完成了重新排列链表的任务。

具体实现

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;
        }
    }
}

  

3. 总结

posted on 2023-04-18 16:36  白露~  阅读(12)  评论(0编辑  收藏  举报