重排链表

110 阅读1分钟

重排链表

给定一个单链表 L 的头节点 head ,单链表 L 表示为:

L0 → L1 → … → Ln - 1 → Ln

请将其重新排列后变为:

L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …

不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

 

示例 1:

plum.jpg

输入:head = [1,2,3,4]
输出:[1,4,2,3]

示例 2:

plum.jpg

输入:head = [1,2,3,4,5]
输出:[1,5,2,4,3]

 

提示:

  • 链表的长度范围为 [1, 5 * 104]
  • 1 <= node.val <= 1000

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

思路1

链表分为left和right

计算出链表的中值,然后算出right的个数

然后把right的链表,隔个插入left链表中

代码1


// 思路:判断right一共有几个,每次while都找right的最后一个插入left相对应的位置
var reorderList = function (head) {
    // 定义size,用来记录中值
    let size = 0;
    // 定义num,用来记录插入的位置
    let num = 0;
    // 定义两指针,指向head
    let pre = head;
    let begin = head;
    // cur指向插入的节点
    let cur;
    // 计算出链表一共有几个节点
    while (pre) {
        pre = pre.next;
        size++;
    }
    // 获得需要插入的个数
    size = parseInt(size / 2);
    // 当需要插入的个数还有,继续循环
    while (size > 0) {
        pre = head;
        cur = head.next;
        // while循环到最后一个节点,取出最后一个节点,以便插入
        while (cur.next) {
            cur = cur.next;
            pre = pre.next;
        }
        pre.next = null;
        begin = head;
        num++;
        let addNum = num * 2 - 2;
        // 找到需要插入的位置,进行插入
        while (addNum > 0) {
            begin = begin.next;
            addNum--;
        }
        let temp = begin.next;
        begin.next = cur;
        cur.next = temp;
        size--;
    }
};

思路2

取得链表的中值,分为两个链表,隔个插入

代码2


// 思路:链表一分为二,然后隔一个节点插入一个节点
var reorderList = function (head) {
    // l1指向head,l2指向中点
    let l1 = head,
        l2 = head;
    let num = 0;
    // 计算中值
    while (l2) {
        l2 = l2.next;
        num++;
    }
    // 分开两个链表
    num = parseInt(num / 2);
    let size = 1;
    l2 = head.next;
    while (size != num && l2) {
        size++;
        l2 = l2.next;
        l1 = l1.next;
    }
    l1.next = null;
    l1 = head;
    // 第二个链表进行翻转,以便插入
    let reverseL2 = null;
    let List2 = reverseL2;
    let pre = l2;
    while (pre) {
        let copy = pre;
        pre = pre.next;
        copy.next = List2;
        List2 = copy;
    }
    num = 0;
    // 当两链表至少有一个有值时,进行插入
    while (l1 || List2) {
        if (num % 2 != 1 && List2) {
            let l1Next = l1.next;
            l1.next = List2;
            l1 = List2;
            List2 = List2.next;
            if (l1Next) {
                l1.next = l1Next;
            } else {
                l1.next = List2;
                List2 = null;
                l1 = null;
            }
        } else {
            l1 = l1.next;
        }
        num++
    }
};
//大佬代码
var reorderList = function (head) {
    let hair = new ListNode(-1, head);
    let left = hair,
        right = hair;
    while (right && right.next) {
        right = right.next;
        right = right.next;
        left = left.next;
    }
    right = left.next;
    left.next = null;
    left = head;
    right = reverse(right);
    while (left && right) {
        let lNext = left.next;
        let rNext = right.next;
        right.next = left.next;
        left.next = right;
        left = lNext;
        right = rNext;
    }
    return hair.next;
};
var reverse = function (head) {
    let temp = new ListNode(-1);
    while (head) {
        let next = head.next;
        head.next = temp.next;
        temp.next = head;
        head = next;
    }
    return temp.next;
}