剑指offer(十四,十五)链表中倒数第k个结点,反转链表

链表中倒数第k个结点
时间限制:1秒 空间限制:32768K
题目描述
输入一个链表,输出该链表中倒数第k个结点。

现在链表题都是要跟“倒立”联系=-=,看到这个问题,自然想到以前用递归巧妙倒序打印链表。

如果是打印倒数第k个节点的val值得话:

var arr = new Array();
var flag = 0;
function FindKthToTail(head, k)
{
    if(head==null) return;
    FindKthToTail(head.next,k);

    if(flag<k)
        arr.push(head.val);
    flag++;
    /* if(flag==k)
         return arr.pop();*/
    return arr.slice(-1)[0];

}

双链表遍历做法AC:

function FindKthToTail(head, k)
{
    if(head==null) return null;
    var i = head, j = head;
    while(--k){
        j = j.next;
        if(!j){
            return null;
        }
    }
    while(j.next){
        i = i.next;
        j = j.next;
    }
    return i;
}

反转链表
时间限制:1秒 空间限制:32768K
题目描述
输入一个链表,反转链表后,输出链表的所有元素

这个无论如何都要用递归了,非常爽。链表每个节点的地址是指向堆区的唯一内存。
eg:链表值和顺序是1,2,3,4,5.
那么第一次递归的结束已经倒着保存了每一层的状态,让ansHead的头结点指向保存着最后一个状态val为5的pHead。
每一层通过Node临时指针tmp重组pHead(颠倒),再打断(pHead.next=null)。

function ListNode(x){
    this.val = x;
    this.next = null;
}

function ReverseList(pHead)
{
    var ansHead, tmp;
    if(!pHead){
        return null;
    }
    if(pHead.next === null){
        return pHead;
    } else {
        ansHead = ReverseList(pHead.next);
    }

    tmp = pHead.next;//保存5节点 &保存4节点
    tmp.next = pHead;//5的下一个节点是4,当前节点是4 &4的下一个节点是3,当前节点是3
    pHead.next = null;//4的下一个节点断掉。&3的下一个节点断掉。
    tmp = null;
    console.log(ansHead);
    return ansHead;
}


function init(linklist,array) {
    linklist = new ListNode(array[0])
    var cur = linklist;
    var len = array.length;
    for(var i = 1; i < len; i++) {
        var tmp = new ListNode(array[i]);
        cur.next = tmp;
        cur = cur.next;
    }
    return linklist;
}

var linklist;
var array = new Array(1,2,3,4,5);
linklist = init(linklist,array);
console.log(ReverseList(linklist));

非递归做法,通过pre和next节点重组链表。
pre保存当前节点的前一个节点,next保存下一个节点,head是当前节点。
每次用head.next = pre来反转,但是要提前用next保存head.next信息,否则发生内存泄漏,找不到断裂的链表。然后让pre,head,next依次向后移动一个节点,继续下一次的指针反转。

    function ListNode(x){
        this.val = x;
        this.next = null;
    }
    function ReverseList(pHead)
    {

        if(pHead==null)
            return null;
        var pre = null;
        var next = null;

        while(pHead!=null){
            next = pHead.next;
            pHead.next = pre;
            pre = pHead;
            pHead = next;
        }
        return pre;
    }

    function init(linklist,array) {
        linklist = new ListNode(array[0])
        var cur = linklist;
        var len = array.length;
        for(var i = 1; i < len; i++) {
            var tmp = new ListNode(array[i]);
            cur.next = tmp;
            cur = cur.next;
        }
        return linklist;
    }

    var linklist;
    var array = new Array(1,2,3,4,5);
    linklist = init(linklist,array);
    console.log(ReverseList(linklist));

转载于:https://www.cnblogs.com/zhangmingzhao/p/8403348.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值