大家好,我是小魔龙,Unity3D软件工程师,VR、AR,虚拟仿真方向,不定时更新软件开发技巧,生活感悟,觉得有用记得一键三连哦。
一、题目
1、算法题目
“给定一个单链表的头结点,将链表重新排列。”
2、题目描述
给定一个单链表 L 的头节点 head ,单链表 L 表示为:
L0 → L1 → … → Ln - 1 → Ln
请将其重新排列后变为:
L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例 1: 输入: head = [1,2,3,4] 输出: [1,4,2,3]
示例 2: 输入: head = [1,2,3,4,5] 输出: [1,5,2,4,3]
二、解题
1、思路分析
因为链表不支持通过下标访问,所以是无法随机访问链表中的任意位置的元素。
比较容易想到的是使用线性表,先用线性表存储链表,然后利用线性表可以使用访问下标的特点。
按照顺序访问指定元素,重新建立链表即可。
2、代码实现
代码参考:
class Solution { public void reorderList(ListNode head) { if (head == null) { return; } List<ListNode> list = new ArrayList<ListNode>(); ListNode node = head; while (node != null) { list.add(node); node = node.next; } int i = 0, j = list.size() - 1; while (i < j) { list.get(i).next = list.get(j); i++; if (i == j) { break; } list.get(j).next = list.get(i); j--; } list.get(i).next = null; } }
3、时间复杂度
时间复杂度:O(N)
其中N是链表中的节点数。
空间复杂度:O(N)
其中N是链表中的节点数,主要是线性表的开销。
三、总结
注意观察一下,就发现目标链表其实就是原链表的做半段和翻转后的右半段合并的结果。
那么是不是可以先找到链表的中间节点,然后将原链表的右半段翻转。
然后将两个新链表合并,就是我们的目标链表。