zoukankan      html  css  js  c++  java
  • 第22题:链表中倒数第k个结点

    题目描述

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

    考点

    鲁棒性:指针为nullptr,链表节点数少于K,输入的K为0

    双指针遍历:只用遍历一次,复杂度O(n)

    unsigned int: 为0的时候,k-1会变成0xFFFFFFFFF,4294967295,进入无限死循环

    第一遍

    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k)
    {
    	//1.鲁棒性检查,nullptr链表,k=0的情况,返回nullptr
    	if (pListHead == nullptr || k == 0)
    		return nullptr;
    
    	//2.定义双指针,第一个指向头节点,第二个指向nullptr
    	ListNode* first = pListHead;
    	ListNode* second = nullptr;
    
    	//3.第一个指针向前走k-1步
    	for (int i = 0; i < k-1; i++)
    	{		
    		//3.1如果k比链表节点大,返回nullptr
    		if (first->m_pNext == nullptr)
    			return nullptr;
    		//3.2 否则,向前走一步
    		else
    			first = first->m_pNext;
    	}
    	
    	//4.第二个指针开始走
    	second = pListHead;
    
    	//5.当第一个指针直到最后一个节点时,第二个指针指向倒数第k个节点
    	while (first->m_pNext!=nullptr)
    	{
    		first = first->m_pNext;
    		second = second->m_pNext;
    	}
    
    	//6.返回第二个指针的值
    	return second;
    }

     注意:

    //3.第一个指针向前走k-1步
        for (int i = 0; i < k-1; i++)
        {        
            //3.1如果k比链表节点大,返回nullptr
            if (first->m_pNext == nullptr)
                return nullptr;
            //3.2 否则,向前走一步
            else
                first = first->m_pNext;
        }

    要先判断first->m_pNext是否存在,再往后走一个


    第二遍

    /*
    struct ListNode {
    	int val;
    	struct ListNode *next;
    	ListNode(int x) :
    			val(x), next(NULL) {
    	}
    };*/
    class Solution {
    public:
        ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
            //1.鲁棒性检查
            if(pListHead==nullptr||k==0)
                return nullptr;
            
            //2.定义双指针
            ListNode* first=pListHead;
            ListNode* second=nullptr;
            
            //3.第一指针先走K-1步
            for(int i=0;i<k-1;i++)
            {
                //3.1 鲁棒性检查,如果k大于链表节点,返回nullptr
                if(first->next==nullptr)
                    return nullptr;
                //3.2 否则往下走一步
                else
                    first=first->next;
            }
            
            //4.第二个指针开始走
            second = pListHead;
            
            //5.直到第一个指针走到最后一个节点,第二个指针就是倒数第K个数,他们的距离是k-1
            while(first->next!=nullptr)
            {
                first=first->next;
                second=second->next;
            }
            
            //6.返回这时的第二个指针
            return second;
        }
    };

    相关题目

    求链表的中间节点,如果链表中的节点总数为奇数,则返回中间节点;如果节点总数是偶数,则返回中间两个节点的任意一个。

    为了解决这个问题,我们也可以定义两个指针,同时从链表的头节点出发,一个指针一次走一步,另一个指针一次走两步。
    当走得快的指针走到链表的末尾时,走得慢的指针正好在链表的中间。 

    struct ListNode {
        int val;
        ListNode *next;
    
    };
    
    ListNode* FindIntermediateNode(ListNode* pHead) {
        if (pHead ==nullptr) 
            return nullptr;
    
        ListNode* pFast = pHead;
        ListNode* pSlow = pHead;
    
        while (pFast != NULL && pFast->next != NULL) {
            pFast = pFast->next->next;
            pSlow = pSlow->next;
        }
    
        return pSlow;
    }
  • 相关阅读:
    WebGL_0008:支持移动端的控制台调试工具
    调整两数组元素使得两数组差值最小
    集五福
    打印机顺序打印
    子弹分发
    字符串分割
    乐观锁、悲观锁
    字符串去重
    数组最后剩下的数字
    shell常用工具
  • 原文地址:https://www.cnblogs.com/lightmare/p/10398758.html
Copyright © 2011-2022 走看看