zoukankan      html  css  js  c++  java
  • 【剑指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,会造成不正确的结果或者程序崩溃。

    总结

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

  • 相关阅读:
    js判断浏览器是否支持flash的方法
    一个基于原生JavaScript开发的、轻量的验证码生成插件
    自适应宽度元素单行文本省略用法探究
    getBoundingClientRect方法获取元素在页面中的相对位置
    修改表单元素中placeholder属性样式、清除IE浏览器中input元素的清除图标和眼睛图标
    tooltip.css-2.0文档
    理解原型与原型链
    javaScript识别网址文本并转为链接文本
    javaScript回调函数
    函数节流(throttle)与函数去抖(debounce)
  • 原文地址:https://www.cnblogs.com/flix/p/12449295.html
Copyright © 2011-2022 走看看