牛客网高频算法题系列-BM14-链表的奇偶重排

题目描述

给定一个单链表,请设定一个函数,将链表的奇数位节点和偶数位节点分别放在一起,重排后输出。
注意是节点的编号而非节点的数值。

原题目见:BM14 链表的奇偶重排

解法一:链表遍历(使用额外空间)

首先,判断如果链表为空或者只有1或2个结点,不用重排,直接返回原链表。

否则,使用2个list额外记录奇数和偶数位的结点,处理过程如下:

  • 遍历链表,分别将奇数和偶数位的结点值放到不同的list中;
  • 按照奇数位在前、偶数位在后的顺序,将2个list中的值重组成新的链表即为重排后的链表,返回之。

解法二:双指针法

同样的,首先要判断如果链表为空或者只有1或2个结点,不用重排,直接返回原链表。

否则,使用odd和even结点分别指向链表的第一个(奇数)和第二个(偶数)结点,然后遍历链表,将奇数位的结点和偶数位的结点分别连接起来,最后,将偶数位的放到奇数位的链表后面,即为重排后的链表。

代码

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. public class Bm014 {
  4. /**
  5. * 使用额外的空间
  6. *
  7. * @param head ListNode类
  8. * @return ListNode类
  9. */
  10. public static ListNode oddEvenList(ListNode head) {
  11. // 如果链表为空或者只有1或2个结点,不用重排
  12. if (head == null || head.next == null || head.next.next == null) {
  13. return head;
  14. }
  15. // 奇数结点
  16. List<Integer> odds = new ArrayList<>();
  17. // 偶数结点
  18. List<Integer> evens = new ArrayList<>();
  19. int i = 1;
  20. while (head != null) {
  21. if (i % 2 == 1) {
  22. odds.add(head.val);
  23. } else {
  24. evens.add(head.val);
  25. }
  26. head = head.next;
  27. i++;
  28. }
  29. ListNode newHead = new ListNode(-1), cur = newHead;
  30. for (Integer val : odds) {
  31. cur.next = new ListNode(val);
  32. cur = cur.next;
  33. }
  34. for (Integer val : evens) {
  35. cur.next = new ListNode(val);
  36. cur = cur.next;
  37. }
  38. return newHead.next;
  39. }
  40. /**
  41. * 双指针法
  42. *
  43. * @param head
  44. * @return
  45. */
  46. public static ListNode oddEvenList2(ListNode head) {
  47. // 如果链表为空或者只有1或2个结点,不用重排
  48. if (head == null || head.next == null || head.next.next == null) {
  49. return head;
  50. }
  51. // 奇数结点
  52. ListNode odd = head;
  53. // 偶数结点,偶数链表头
  54. ListNode evenHead = head.next, even = evenHead;
  55. while (even != null && even.next != null) {
  56. // odd连接奇数位结点
  57. odd.next = even.next;
  58. odd = odd.next;
  59. // even连接偶数位结点
  60. even.next = odd.next;
  61. even = even.next;
  62. }
  63. // 最后将odd链表的最后一个结点指向even链表的表头
  64. odd.next = evenHead;
  65. return head;
  66. }
  67. public static void main(String[] args) {
  68. ListNode head = ListNode.testCase5();
  69. System.out.println("原链表为");
  70. ListNode.print(head);
  71. System.out.println("重排后的链表为");
  72. ListNode.print(oddEvenList(head));
  73. ListNode.print(oddEvenList2(head));
  74. }
  75. }

牛客网高频算法题系列-BM14-链表的奇偶重排 - 图1
牛客网高频算法题系列-BM14-链表的奇偶重排 - 图2
相信坚持的力量!