加载中...
328-奇偶链表(Odd Even Linked List)
发表于:2021-12-03 | 分类: 中等
字数统计: 1.4k | 阅读时长: 6分钟 | 阅读量:

原文链接: https://leetcode-cn.com/problems/odd-even-linked-list

英文原文

Given the head of a singly linked list, group all the nodes with odd indices together followed by the nodes with even indices, and return the reordered list.

The first node is considered odd, and the second node is even, and so on.

Note that the relative order inside both the even and odd groups should remain as it was in the input.

You must solve the problem in O(1) extra space complexity and O(n) time complexity.

 

Example 1:

Input: head = [1,2,3,4,5]
Output: [1,3,5,2,4]

Example 2:

Input: head = [2,1,3,5,6,4,7]
Output: [2,3,6,7,1,5,4]

 

Constraints:

  • n == number of nodes in the linked list
  • 0 <= n <= 104
  • -106 <= Node.val <= 106

中文题目

给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。

请尝试使用原地算法完成。你的算法的空间复杂度应为 O(1),时间复杂度应为 O(nodes),nodes 为节点总数。

示例 1:

输入: 1->2->3->4->5->NULL
输出: 1->3->5->2->4->NULL

示例 2:

输入: 2->1->3->5->6->4->7->NULL 
输出: 2->3->6->7->1->5->4->NULL

说明:

  • 应当保持奇数节点和偶数节点的相对顺序。
  • 链表的第一个节点视为奇数节点,第二个节点视为偶数节点,以此类推。

通过代码

高赞题解

方法一:分离节点后合并

如果链表为空,则直接返回链表。

对于原始链表,每个节点都是奇数节点或偶数节点。头节点是奇数节点,头节点的后一个节点是偶数节点,相邻节点的奇偶性不同。因此可以将奇数节点和偶数节点分离成奇数链表和偶数链表,然后将偶数链表连接在奇数链表之后,合并后的链表即为结果链表。

原始链表的头节点 head 也是奇数链表的头节点以及结果链表的头节点,head 的后一个节点是偶数链表的头节点。令 evenHead = head.next,则 evenHead 是偶数链表的头节点。

维护两个指针 oddeven 分别指向奇数节点和偶数节点,初始时 odd = headeven = evenHead。通过迭代的方式将奇数节点和偶数节点分离成两个链表,每一步首先更新奇数节点,然后更新偶数节点。

  • 更新奇数节点时,奇数节点的后一个节点需要指向偶数节点的后一个节点,因此令 odd.next = even.next,然后令 odd = odd.next,此时 odd 变成 even 的后一个节点。

  • 更新偶数节点时,偶数节点的后一个节点需要指向奇数节点的后一个节点,因此令 even.next = odd.next,然后令 even = even.next,此时 even 变成 odd 的后一个节点。

在上述操作之后,即完成了对一个奇数节点和一个偶数节点的分离。重复上述操作,直到全部节点分离完毕。全部节点分离完毕的条件是 even 为空节点或者 even.next 为空节点,此时 odd 指向最后一个奇数节点(即奇数链表的最后一个节点)。

最后令 odd.next = evenHead,将偶数链表连接在奇数链表之后,即完成了奇数链表和偶数链表的合并,结果链表的头节点仍然是 head

fig1

[sol1-Java]
class Solution { public ListNode oddEvenList(ListNode head) { if (head == null) { return head; } ListNode evenHead = head.next; ListNode odd = head, even = evenHead; while (even != null && even.next != null) { odd.next = even.next; odd = odd.next; even.next = odd.next; even = even.next; } odd.next = evenHead; return head; } }
[sol1-JavaScript]
var oddEvenList = function(head) { if (head === null) { return head; } let evenHead = head.next; let odd = head, even = evenHead; while (even !== null && even.next !== null) { odd.next = even.next; odd = odd.next; even.next = odd.next; even = even.next; } odd.next = evenHead; return head; };
[sol1-C++]
class Solution { public: ListNode* oddEvenList(ListNode* head) { if (head == nullptr) { return head; } ListNode* evenHead = head->next; ListNode* odd = head; ListNode* even = evenHead; while (even != nullptr && even->next != nullptr) { odd->next = even->next; odd = odd->next; even->next = odd->next; even = even->next; } odd->next = evenHead; return head; } };
[sol1-Golang]
func oddEvenList(head *ListNode) *ListNode { if head == nil { return head } evenHead := head.Next odd := head even := evenHead for even != nil && even.Next != nil { odd.Next = even.Next odd = odd.Next even.Next = odd.Next even = even.Next } odd.Next = evenHead return head }
[sol1-Python3]
class Solution: def oddEvenList(self, head: ListNode) -> ListNode: if not head: return head evenHead = head.next odd, even = head, evenHead while even and even.next: odd.next = even.next odd = odd.next even.next = odd.next even = even.next odd.next = evenHead return head
[sol1-C]
struct ListNode* oddEvenList(struct ListNode* head) { if (head == NULL) { return head; } struct ListNode* evenHead = head->next; struct ListNode* odd = head; struct ListNode* even = evenHead; while (even != NULL && even->next != NULL) { odd->next = even->next; odd = odd->next; even->next = odd->next; even = even->next; } odd->next = evenHead; return head; }

复杂度分析

  • 时间复杂度:$O(n)$,其中 $n$ 是链表的节点数。需要遍历链表中的每个节点,并更新指针。

  • 空间复杂度:$O(1)$。只需要维护有限的指针。

统计信息

通过次数 提交次数 AC比率
135628 207034 65.5%

提交历史

提交时间 提交结果 执行时间 内存消耗 语言

相似题目

题目 难度
分隔链表 中等
上一篇:
327-区间和的个数(Count of Range Sum)
下一篇:
329-矩阵中的最长递增路径(Longest Increasing Path in a Matrix)
本文目录
本文目录