【算法-LeetCode】328. 奇偶链表(单链表;多指针)

328. 奇偶链表 - 力扣(LeetCode)

文章起笔:2021年11月14日14:56:15

问题描述及示例

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

请尝试使用原地算法完成。你的算法的空间复杂度应为 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

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/odd-even-linked-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

我的题解(多指针)

链表类的题目一般都要运用指针思想。本题也不例外,而且本题要用到四个指针:

  • oddRear 用于指向奇链表的尾部。
  • evenHead 用于指向偶数表的头部。
  • evenRear 用于指向偶数表的尾部。
  • nextOdd 用于指向下一个将要被处理的奇数节点。

整个过程其实可以抽象为不断地翻转两个节点,其中一个节点就是 nextOdd 指向的那个节点,而另外一个节点其实不是单纯地指某个节点,而是由偶数链表抽象成的一个大节点

花了点时间做了一张动态图来说明:

请添加图片描述

交换节点的部分过程

这个过程用文字还是不好表述的,建议自己用纸笔画一下相应过程以便理解。

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var oddEvenList = function(head) {
  // 如果链表的长度小于3,那么就可以直接返回原链表,下面的交换逻辑最少需要三个非空节点
  if(!head || !head.next || !head.next.next) {
    return head;
  }
  // 初始化四个指针
  let oddRear = head;
  // 注意evenHead指针和evenRear指针初始指向都是第二个节点,且evenHead指针的指向是不变的
  let evenHead = head.next;
  let evenRear = head.next;
  let nextOdd = evenRear.next;
  // 如果evenRear和evenRear.next指向的节点都不为空,则继续交换过程
  // 注意这里我一开始只写了evenRear非空这个条件,但是后来发现,
  // 当链表节点数为偶数时就会出现错误【Can't read propety 'next' of null】
  while(evenRear && evenRear.next) {
    // 下面三句就是交换节点的逻辑,具体可以看上面的动态图
    oddRear.next = evenRear.next;
    evenRear.next = nextOdd.next;
    nextOdd.next = evenHead;
    // 下面三句是更新oddRear、evenRear、nextOdd三个指针的指向的逻辑,具体看上方动态图
    oddRear = oddRear.next;
    evenRear = evenRear.next;
    // 注意这里要根据evenRear是否为空来判断nextOdd的值,否则会出错
    nextOdd = evenRear ? evenRear.next : null;
  }
  return head;
};


提交记录
执行结果:通过
70 / 70 个通过测试用例
执行用时:76 ms, 在所有 JavaScript 提交中击败了87.01%的用户
内存消耗:39.8 MB, 在所有 JavaScript 提交中击败了86.33%的用户
时间:2021/11/14 14:57

如果能够理解【将偶数链表看做一个大节点】这种思想,其实整个过程还是比较容易推导的。

PS:画动态图还是挺麻烦的……

官方题解

更新:2021年7月29日18:43:21

因为我考虑到著作权归属问题,所以【官方题解】部分我不再粘贴具体的代码了,可到下方的链接中查看。

【更新结束】

更新:2021年11月14日14:58:32

参考:奇偶链表 - 奇偶链表 - 力扣(LeetCode)

【更新结束】

有关参考

暂无

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值