码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-02-02 11:31:53      阅读:142      评论:0      收藏:0      [点我收藏+]

标签:reverse   问题   tno   g++   非递归   blog   cti   ever   地址   

链表中倒数第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 热度指数:199432
题目描述
输入一个链表,反转链表后,输出链表的所有元素

这个无论如何都要用递归了,非常爽。链表每个节点的地址是指向堆区的唯一内存。
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));

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

标签:reverse   问题   tno   g++   非递归   blog   cti   ever   地址   

原文地址:https://www.cnblogs.com/zhangmingzhao/p/8403348.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!