题目
给定一个单向链表,重新排列链表
- 规则
- 例1:
- 排序前:n1->n2->n3->n4
- 排序后:n1->n4->n2->n3
- 例2:
- 排序前:n1->n2->n3->n4->n5
- 排序后:n1->n5->n2->n4->n3
- 要求
- 需要实际交换节点
- 不能只改变节点内部的值
分析
- 链表的特点
- 可以很方便的添加、删除节点
- 没有下标,无法随机读取节点
- 使用线性表来支持下标访问链表节点
题解
public class ReorderListDemo {
/**
* 重排链表算法
*
* @param head
*/
public void reorderList(ListNode head) {
List<ListNode> list = new ArrayList<>();
while (head != null) {
list.add(head);
head = head.next;
}
int left = 0, right = list.size() - 1;
while (left < right - 1) {
list.get(left).next = list.get(right);
left++;
list.get(right).next = list.get(left);
right--;
}
list.get(right).next = null;
}
/**
* 以下为测试代码
*
* @param args
*/
public static void main(String[] args) {
ReorderListDemo demo = new ReorderListDemo();
ListNode node1 = demo.buildList();
demo.printList("排序前: ", node1);
demo.reorderList(node1);
demo.printList("排序后: ", node1);
}
private ListNode buildList() {
ListNode node1 = new ListNode(1);
ListNode node2 = new ListNode(2);
ListNode node3 = new ListNode(3);
ListNode node4 = new ListNode(4);
ListNode node5 = new ListNode(5);
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
return node1;
}
private void printList(String msg, ListNode node) {
System.out.print(msg);
while (node != null) {
System.out.print(node.val);
node = node.next;
if (node != null) System.out.print(" -> ");
}
System.out.println();
}
}
class ListNode {
int val;
ListNode next;
ListNode(int val) {
this.val = val;
}
}
总结
此题目主要考察答题者对链表的熟悉程度。链表的特点是添加、删除节点方便;但是没有下标,无法随机读取节点。所以很容易想到增加链表的随机访问能力即可解决此排序问题