算法思想一:数组
解题思路:
因为链表不支持下标访问,所以我们无法随机访问链表中任意位置的元素。
因此比较容易想到的一个方法是,我们利用线性表存储该链表,然后利用线性表可以下标访问的特点,直接按顺序访问指定元素,重建该链表即可。
因此比较容易想到的一个方法是,我们利用线性表存储该链表,然后利用线性表可以下标访问的特点,直接按顺序访问指定元素,重建该链表即可。
算法步骤:
1、初始化空数组res,遍历链表将链表结点存储到数组中
2、设置双指针i,j
按照题目,res[i].next = res[j],指针 i 加1
再拼接 res[j] 结点, res[j].next = res[i], 指针 j 减1
循环到 i >= j 跳出循环
代码展示:
Python版本
# class ListNode: # def __init__(self, x): # self.val = x # self.next = None # # # @param head ListNode类 # @return void # class Solution: def reorderList(self , head ): # write code here if not head: return # 初始化数组 res = [] node = head while node: res.append(node) node = node.next # 进行链表结点交换 i, j = 0, len(res) - 1 while i < j: res[i].next = res[j] i += 1 if i == j: break res[j].next = res[i] j -= 1 # 指明最后 res[i].next = None
复杂度分析:
时间复杂度O(N):N是链表的结点数量,遍历链表、数组构建新链表
空间复杂度O(N):使用额外的数组空间
算法思想二:寻找链表中点 + 链表逆序 + 合并链表
解题思路:
1、找中点的话,可以使用快慢指针。快指针一次走两步,慢指针一次走一步,当快指针走到终点的话,慢指针会刚好到中点。如果节点个数是偶数的话,slow 走到的是左端点,利用这一点,我们可以把奇数和偶数的情况合并,不需要分开考虑。
2、链表逆序的话,参考 https://blog.nowcoder.net/n/d259b250747b4085bc7975f102d248c4
3、合并链表,两个指针分别向后移动就可以。
2、链表逆序的话,参考 https://blog.nowcoder.net/n/d259b250747b4085bc7975f102d248c4
3、合并链表,两个指针分别向后移动就可以。
图解:
链表:{1,2,3,4,5,6}
| 步骤 | 操作 | 链表 |
| 1 | 寻找链表中点,将链表分为两半 | {1,2,3} {4,5,6} |
| 2 | 将后半链表反转 | {1,2,3} {6,5,4} |
| 3 | 合并两个链表 | {1,6,2,5,3,4} |
代码展示:
JAVA版本
public class Solution {
public void reorderList(ListNode head) {
if (head == null || head.next == null || head.next.next == null) {
return;
}
//找中点,链表分成两个
ListNode slow = head;
ListNode fast = head;
while (fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
ListNode newHead = slow.next;
slow.next = null;
//第二个链表倒置,反转后半部分链表
newHead = reverseList(newHead);
//链表节点依次连接
while (newHead != null) {
ListNode temp = newHead.next;
newHead.next = head.next;
head.next = newHead;
head = newHead.next;
newHead = temp;
}
}
private ListNode reverseList(ListNode head) {
if (head == null) {
return null;
}
ListNode tail = head;
head = head.next;
tail.next = null;
while (head != null) {
ListNode temp = head.next;
head.next = tail;
tail = head;
head = temp;
}
return tail;
}
} 复杂度分析:
时间复杂度O(N):N是链表的结点数量,遍历链表、重组链表
空间复杂度O(1):使用常数级空间指针



京公网安备 11010502036488号