lletcode之链表重组

题目

 

 解决

思路一:1.使用两个数组,将链表断开,push进入数组中,并构建一个反向数组。2.循环两个数组的前半部分元素,依次重组链表。(蠢办法)

题目要求not modify the values in the list's nodes, only nodes itself may be changed. 因此将结果链表的值赋给head是不可行的。

/**
 * 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 {void} Do not return anything, modify head in-place instead.
 */
var reorderList = function(head) {
    if(head === null || head.next === null){
        return
    }
    // 利用数组,将链表中的数据依次存入数组中,并构造一个反转数组,依次连接正向数组和反向数组的前一半的元素即可
    let newHead = head
    let t2 = [newHead.val]
    while(newHead.next) {
        t2.push(newHead.next.val)
        newHead = newHead.next
    }
    let t1 = JSON.parse(JSON.stringify(t2)) // 保存反转之前的数组
    t2.reverse()
    let t = new ListNode(0) // 哑结点,可以更改头结点的链表
    let temp = t // 引用类型传递,t的任何一个节点发生改变都会同步到temp
    let len = Math.floor(t1.length / 2)
    for(let i = 0; i < len; i++) {
        t.next = new ListNode(t1[i])
        t.next.next = new ListNode(t2[i])
        t = t.next.next
        if(i === len - 1) {
            t.next = new ListNode(t1[i+1])
        }
    }
    // 下面的代码,为什么不能直接用head = temp.next?
    temp = temp.next
    while(head) {
        head.val = temp.val
        head = head.next
        temp = temp.next
    }
    return head 
};

思路二:使用一个数组,将链表断开push进数组中,然后通过头尾双指针将数组中的元素重组为链表。遍历条件:头指针下标小于尾指针下标(较思路一好,内存占用少,运行时间少)

/**
 * 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 {void} Do not return anything, modify head in-place instead.
 */
var reorderList = function(head) {
    if(head === null || head.next === null) {
        return
    }
    let t = [], temp = null
    while(head) {
        temp = head.next
        head.next = null // 为什么head.next的值为null了,temp !== null, 这地方不是引用传递吗?
        t.push(head) // 将head中的节点push进数组中,为了满足题目要求的只能改变节点,不能改变节点的值,也就是不能直接通过改变head.val来实现,只能改变节点的next指向。
        head = temp
    }
    let len = t.length
    let i = -1, j = len
    while(++i < --j) {
        t[i].next = t[j]
        j !== i+1 && (t[j].next = t[i+1])     
    }
};

链表就是一环扣一环,顺藤摸瓜的感觉。

在思路二中,通过下面的while循环重组链表,用数组[ [1], [2], [3], [4], [5] ]模拟一下就明白了。

 while(++i < --j) {
        t[i].next = t[j]
        j !== i+1 && (t[j].next = t[i+1])     
    }

 

 

 

posted @ 2020-10-21 18:02  半忧夏  阅读(228)  评论(0编辑  收藏  举报