题目描述
Leetcode题目链接
给定单链表,实现反转与洗牌操作
思路分析
首先取得链表长度,然后反转链表的后一半部分。然后开始链表重新排序(类似于洗牌一样的)
代码实现
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
//获取链表长度
private int getListOfLength(ListNode head) {
int n = 0;
while (head != null) {
n++;
head = head.next;
}
return n;
}
//反转链表
private ListNode reverseList(ListNode head) {
ListNode pre = head;
ListNode p = pre.next;
ListNode next = null;
while (p != null) {
next = p.next;
p.next = pre;
pre = p;
p = next;
}
head.next = null; //去掉头结点的环
return pre;
}
//重新排序链表(链表洗牌)
public void reorderList(ListNode head) {
if (head == null || head.next == null) {
return;
}
int n = getListOfLength(head); //链表长度
int half = n/2; //链表长度的一半
if (n % 2 == 1) { //如果链表长度为奇数
half++;
}
ListNode leftEnd = head; //链表左半部分的结束位置,初始化为head
for (int i = 1; i < half; i++) {
leftEnd = leftEnd.next;
}
ListNode rightStart = leftEnd.next; //链表右半部分的开始位置
rightStart = reverseList(rightStart); //反转链表的右半部分
leftEnd.next = null; //开始洗牌,将链表正中央的链断开
ListNode left = head; //左半部分的开始位置
ListNode right = rightStart; //右半部分的开始位置
boolean flag = true; //实现交替洗牌
ListNode next = null; //用来存储下一张洗的牌
//洗牌
while (right != null) {
if (flag) {
next = left.next;
left.next = right;
left = next;
} else {
next = right.next;
right.next= left;
right = next;
}
flag = !flag;
}
}
}