zoukankan      html  css  js  c++  java
  • careercup-链表 2.2

    2.2 实现一个算法,找到单链表中倒数第k个节点。

    这道题的考点在于我们怎么在一个单链表中找到倒数第n个元素? 由于是单链表,所以我们没办法从最后一个元素数起,然后数n个得到答案。 但这种最直观的思路显然是没错的,那我们有没有办法通过别的方式,从最后的元素数起数 n个来得到我们想要的答案呢。

    这个次序颠倒的思路可以让我们联想到一种数据结构:栈。

    我们如果遍历一遍单链表,将其中的元素压栈,然后再将元素一一出栈。那么, 第n个出栈的元素就是我们想要的。

    那我们是不是需要显式地用栈这么一个结构来做这个问题呢?答案是否。看到栈,我们应当 要想到递归,它是一种天然使用栈的方式。所以,第一种解决方案用递归,让栈自己帮我 们从链表的最后一个元素数起。

    思路很简单,如果指向链表的指针还未空,就不断递归。当指针为空时开始退递归,这个过 程n不断减1,直接等于1,即可把栈中当前的元素取出。代码如下:

    node *pp;
    int nn;
    void findNthToLast1(node *head){
        if(head==NULL) return;
        findNthToLast1(head->next);
        if(nn==1) pp = head;
        --nn;
    }

    虽然我们没办法从单链表的最后一个元素往前数,但如果我们维护两个指针, 它们之间的距离为k。然后,我将这两个指针同步地在这个单链表上移动,保持它们的距离 为k不变。那么,当第二个指针指到空时,第一个指针即为所求。很tricky的方法, 将这个问题很漂亮地解决了。

    C++实现代码:

    #include<iostream>
    #include<new>
    using namespace std;
    
    struct ListNode
    {
        int val;
        ListNode *next;
        ListNode(int x):val(x),next(NULL) {}
    };
    
    void createList(ListNode *&L)
    {
        int arr[10]= {1,2,3,2,5,6,7,3,9,1};
        int i;
        ListNode *p=NULL;
        for(i=0; i<10; i++)
        {
            ListNode *tmp=new ListNode(arr[i]);
            if(L==NULL)
            {
                L=tmp;
                p=tmp;
            }
            else
            {
                p->next=tmp;
                p=tmp;
            }
        }
    }
    
    ListNode *findKNode(ListNode *L,int k)
    {
        if(L==NULL)
            return NULL;
        ListNode *p=L;
        ListNode *q=L;
        int count=0;
        while(q)
        {
            if(count==k)
            {
                p=p->next;
                q=q->next;
            }
            else
            {
                count++;
                q=q->next;
            }
        }
        if(count==k)
            return p;
        else
            return NULL;
    }
    
    int main()
    {
        ListNode *head=NULL;
        createList(head);
        ListNode *p=head;
        while(p)
        {
            cout<<p->val<<" ";
            p=p->next;
        }
        cout<<endl;
        p=findKNode(head,11);
        if(p)
            cout<<p->val<<endl;
    }
  • 相关阅读:
    vue-fullcalendar插件
    iframe 父框架调用子框架的函数
    关于调试的一点感想
    hdfs 删除和新增节点
    hadoop yarn 实战错误汇总
    Ganglia 安装 No package 'ck' found
    storm on yarn(CDH5) 部署笔记
    spark on yarn 安装笔记
    storm on yarn安装时 提交到yarn失败 failed
    yarn storm spark
  • 原文地址:https://www.cnblogs.com/wuchanming/p/4141244.html
Copyright © 2011-2022 走看看