zoukankan      html  css  js  c++  java
  • 数据结构-链表中倒数第K个节点

    题目:输入一个链表,输出该链表中倒数第K个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如一个链表有6个节点,从头节点开始他们的值依次为1,2,3,4,5,6.这个链表的倒数第三个节点是值为4的节点。

    分析:不能多次遍历链表,只能一次遍历。

    /*
    剑指offer面试题15
    */
    #include <iostream>
    
    using namespace std;
    
    struct ListNode{
        ListNode* Next;
        int data;
    };
    
    
    /*
    把题目看错,看成删除了。但是删除功能可以实现,
    同样存在和题目一样的问题,存在多次遍历问题。
    为了代码质量更好要求只遍历一次。
    */
    ListNode* DeleteKnode(ListNode** head,int k){
        if(*head == NULL || k <= 0){
            return NULL;
        }
    
        ListNode* p = *head;
        ListNode* q = new ListNode;
        int count = 0;
        int num = 0;
    
        while(p != NULL){
            p = p->Next;
            count++;
        }
        //加入k大于链表长度,非法
        if(k > count){
            return NULL;
        }
        //删除尾节点
        if(k == 1){
            p = *head;
            int i=1;
            while(i<(count-1)){
                p = p->Next;
                i++;
            }
            q = p->Next;
            delete q;
            q = NULL;
            p->Next = NULL;
            return *head;
        }
        //删除头节点
        if(k == count){
            p = *head;
            q = p->Next;
            delete p;
            p = NULL;
            return q;
        }
    
        else{
            p = *head;
            while(p != NULL && (count-k-1) > num){
                num++;
                p = p->Next;
            }
            q = p->Next;
            p->Next = q->Next;
            delete q;
            q = NULL;
        }
    
        return p;
    }
    
    void Print(ListNode** head,int k){
        if(*head == NULL || k <= 0){
            return;
        }
    
        ListNode* first = *head;
        int length = 0;
        for(int i=0;i<k-1;++i){
            if(first->Next != NULL){    //这是关键步骤!!
                first = first->Next;
                length++;
            }
            else{
                return;
            }
        }
    
        ListNode* second = *head;
        while(first->Next != NULL){
            first = first->Next;
            length++;
            second = second->Next;
        }
    
        cout << second->data << endl;
    
    }
    
    int main()
    {
        ListNode* head = new ListNode;
        ListNode* One = new ListNode;
        ListNode* Two = new ListNode;
        ListNode* tail = new ListNode;
    
        head->data = 0;
        head->Next = One;
        One->data = 1;
        One->Next = Two;
        Two->data = 2;
        Two->Next = tail;
        tail->data = 3;
        tail->Next = NULL;
    
        int k;
    
        cin >> k;
    
    /*
        ListNode* p = DeleteKnode(&head,k);
    
        while(p != NULL){
            cout << p->data << " ";
            p = p->Next;
        }
    */
    
        Print(&head,k);
    
        return 0;
    }
  • 相关阅读:
    springboot访问redis序列化问题
    观察者模式在源码中的使用
    抽象工厂模式在源码中的使用
    工厂方法模式在源码中的应用
    策略模式的应用
    springcloud实现限流
    Elasticsearch
    java8新特性(二)StreamApi
    thinkpaidE450 win10 进入bios
    restframe_work2
  • 原文地址:https://www.cnblogs.com/wn19910213/p/3723347.html
Copyright © 2011-2022 走看看