重排链表算法

描述

将给定的单链表\ L L: L_0→L_1→…→L_{n-1}→L_ nL0​→L1​→…→Ln−1​→Ln​
重新排序为:L_0→L_n →L_1→L_{n-1}→L_2→L_{n-2}→…L0​→Ln​→L1​→Ln−1​→L2​→Ln−2​→…
要求使用原地算法,不能只改变节点内部的值,需要对实际的节点进行交换。

数据范围:链表长度 0 \le n \le 200000≤n≤20000 ,链表中每个节点的值满足 0 \le val \le 10000≤val≤1000

要求:空间复杂度 O(n)O(n) 并在链表上进行操作而不新建链表,时间复杂度 O(n)O(n)

进阶:空间复杂度 O(1)O(1) , 时间复杂度 O(n)O(n)

示例1

输入:

{1,2,3,4}

复制返回值:

{1,4,2,3}

复制说明:

给定head链表1->2->3->4, 重新排列为 1->4->2->3,会取head链表里面的值打印输出 1      

解题思路:

  1. 边界处理
  2. 找到中间节点
  3. 翻转后半段链表
  4. 归并链表

复制代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

/**

 * Definition for singly-linked list.

 * class ListNode {

 *     int val;

 *     ListNode next;

 *     ListNode(int x) {

 *         val = x;

 *         next = null;

 *     }

 * }

 */

public class Solution {

    public void reorderList(ListNode head) {

        if(head == null || head.next == nullreturn;

        ListNode mid = getMid(head);

        ListNode midNext = mid.next;

        mid.next = null;

        ListNode prev = null;

        ListNode cur = midNext;

        while(cur != null){

            ListNode next = cur.next;

            cur.next = prev;

            prev = cur;

            cur = next;

        }

        ListNode node = head;

        while(node != null && prev != null){

            ListNode n1 = node.next;

            ListNode n2 = prev.next;

            node.next = prev;

            prev.next = n1;

            node = n1;

            prev = n2;

        }

    }

    public ListNode getMid(ListNode head){

        ListNode slow = head;

        ListNode fast = head;

        while(fast.next != null && fast.next.next != null){

            slow = slow.next;

            fast = fast.next.next;

        }

        return slow;

    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值