• 【剑指Offer-代码的鲁棒性】面试题22:链表中倒数第k个节点


    题目描述

    输入一个链表,输出该链表中倒数第k个结点(k从1开始)。

    思路1

    假设链表中共有n个节点,倒数第k个节点即为正数第n-k+1个节点(正数倒数编号都从1开始)。所以我们首先要将链表遍历一遍获得长度n,然后再移动到第n-k+1个节点即可。对应代码如下:

    /*
    struct ListNode {
    	int val;
    	struct ListNode *next;
    	ListNode(int x) :
    			val(x), next(NULL) {
    	}
    };*/
    class Solution {
    public:
        ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
            if(pListHead==nullptr || k==0)
                return nullptr;
            
            int n = 1;
            ListNode* temp = pListHead;
            while(temp->next!=nullptr){
                temp = temp->next;
                n++;
            }
            if(n<k)
                return nullptr;
            
            ListNode* node = pListHead;
            for(int i=1; i<n-k+1; i++)
                node = node->next;
            return node;
        }
    };
    

    思路2

    思路1主要的缺点是要先把链表遍历一遍来获取链表的长度。为了解决这个问题,我们可以设置两个指针p1和p2, p1和p2的初始值均为链表头head。首先将p1移动k-1步,此时p1还剩n-k+1步到达链表尾。从第k步开始,p2也开始移动,这样等p1到达链表尾时,p2位于链表第n-k+1个节点,也就是链表倒数第k个节点。

    代码如下:

    /*
    struct ListNode {
    	int val;
    	struct ListNode *next;
    	ListNode(int x) :
    			val(x), next(NULL) {
    	}
    };*/
    class Solution {
    public:
        ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
            if(pListHead==nullptr || k==0)  //unsigned int 0-1!=-1,会造成程序崩溃
                return nullptr;
            
            ListNode* p1 = pListHead;
            ListNode* p2 = pListHead;
            for(unsigned int i=0; i<k-1; i++){
                if(p1->next==nullptr)    // k大于链表长度
                    return nullptr;
                p1 = p1->next;
            }
            while(p1->next!=nullptr){
                p1 = p1->next;
                p2 = p2->next;
            }
            return p2;
        }
    };
    

    注意点

    1、链表头pListHead为空;
    2、链表节点总数小于k;
    3、k是无符号整数,当k=0时,k-1=4294967295,会造成不正确的结果或者程序崩溃。

    总结

    当链表问题用一个指针不好解决时,可以尝试使用两个指针,让其中一个指针走得快,另一个走得慢。

  • 相关阅读:
    乱谈B2C系统算是今年的总结吧
    浅谈领域模型驱动中表的设计方法
    作业调度小软件
    使用Mutex实现会话状态下单实例运行和系统范围内单实例运行
    几种特殊的类型设计。
    XCommunity权限控制和配置体系
    某个最近不知道为啥很火的小题目的LINQ实现
    C#关于参数为null(空值)的方法调用,重载顺序选择彻底研究
    好吧,不得不说说这篇在首页恶心人的文章
    “九种不够面向对象的对象“的在实际项目中的合理运用
  • 原文地址:https://www.cnblogs.com/flix/p/12449295.html
Copyright © 2020-2023  润新知