zoukankan      html  css  js  c++  java
  • 剑指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));
    
  • 相关阅读:
    2017免费获取正版win10的方法
    Apache <Directory>… </Directory>配置
    针对left join以及limit的两条优化小技巧
    win10打印机突然无法启动
    mysql中的分组统计函数及其用法实例
    程序猿的日常生活-雨中
    java中的反射
    mysql中的截取函数及其实例
    集合与数组
    方法重写
  • 原文地址:https://www.cnblogs.com/zhangmingzhao/p/8403348.html
Copyright © 2011-2022 走看看