題目鏈接
328. 奇偶鏈表
題目描述
解題思路
暴力法
先統計鏈表長度,然後根據鏈表長度決定兩兩交換鏈表中的元素的次數即可。(如果不明白自己畫個圖即可)
拆分爲奇偶鏈表在拼接
維護兩個指針 odd 和 even 分別指向奇數節點和偶數節點,初始時 odd = head,even = evenHead。通過迭代的方式將奇數節點和偶數節點分離成兩個鏈表,每一步首先更新奇數節點,然後更新偶數節點。最後把偶數節點拼接在奇數節點後面即可。
AC代碼
解法一
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode oddEvenList(ListNode head) {
if(head == null || head.next == null || head.next.next ==null) return head;
ListNode countNode = head;
int count = 0;
while(countNode != null){
count++;
countNode = countNode.next;
}
//鏈表的經典解法,3指針!!!!!!
ListNode dum = head;
ListNode pre = head;
ListNode cur = head.next;
ListNode temp = cur.next;
int tot = 0;
//根據鏈表長度決定兩兩元素交換的次數
if(count % 2 == 0) tot = count / 2 - 1;
else tot = count / 2;
while(tot > 0){
int num = tot;
while(num > 0){
pre.next = temp;
cur.next = temp.next;
temp.next = cur;
pre = cur;
if(cur.next != null) cur = cur.next;
if(cur.next != null) temp = cur.next;
num--;
}
tot--;
dum = dum.next;
pre = dum;
cur = pre.next;
temp = cur.next;
}
return head;
}
}
解法二
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode oddEvenList(ListNode head) {
if(head == null || head.next == null || head.next.next ==null) return head;
ListNode odd = head;
ListNode even = head.next;
ListNode evenHead = even;
while(true){
odd.next = even.next;
if(even.next != null) odd = even.next;
else break;
if(odd.next != null) even.next = odd.next;
else break;
if(odd.next != null) even = odd.next;
}
odd.next = evenHead;
even.next = null;
return head;
}
}