zoukankan      html  css  js  c++  java
  • 剑指offer-链表中倒数第k个结点

    链表中倒数第k个结点

    一、题目描述

    输入一个链表,输出该链表中倒数第k个结点。

    二、题目的思路

    这道题让我想到了单链表逆置的题目。

    思路1

    将整个链表进行逆转,要找到第k个结点只需要将新的链表遍历一下就可以了。

    思路2

    开辟一个足够大的数组,将链表有序的放入数组,要知道倒数第k个结点,在数组中非常简单。但是这个方法在实际应用中不采用,因为内存中很可能有很多无效的结点,全部放入新的数组,非常浪费空间。

    思路3

    和思路2类似,用栈的方式存储链表的值,再依次弹出k次就是第k个结点。

    貌似思路1的思路很好,很完美了,但是问题来了。如果没有给定链表是带头节点的还是不带头节点的,问题就变得麻烦了。两种处理方式有一些差异,那怎么样做到无差异化呢。

    思路4

    找两个指针都指向第一个结点(不管是头结点还是首结点)然后遍历,遍历时,让第一个指针往后走k-1步,到达第k个结点,这时候开始两个指针一起动。当第一个结点到达末尾时,第二指针所在的位置就是倒数第k个结点。

    三、算法实现

    3.1、Java实现

    /*
    public class ListNode {
        int val;
        ListNode next = null;
    
        ListNode(int val) {
            this.val = val;
        }
    }*/
    public class Solution {
        public ListNode FindKthToTail(ListNode head,int k) {
            if(head==null||k<=0){
                return null;
            }
            ListNode pre=head;
            ListNode last=head;
            for(int i=1;i<k;i++){
                if(pre.next!=null){
                    pre=pre.next;
                }else{
                    return null;
                }
            }
            while(pre.next!=null){
                pre = pre.next;
                last=last.next;
            }
            return last;
        }
    }
    

    3.2、C++实现版

    /*
    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;
            ListNode *pre,*last;
            pre=pListHead;
            last=pListHead;
            for(int i=1;i<k;i++){
                if(pre->next==nullptr) return nullptr;
                else pre=pre->next;
            }
            while(pre->next){
                pre=pre->next;
                last=last->next;
            }
            return last;
        }
    };
    

    在解决这里的问题的时候,还发现了一个语法上的问题。pnullptr或者pNULL这样的写法,在C++里,p==nullptr等价于!p,p!=nullptr等价于p,当然这种等价是指布尔属性。
    因此改进后的代码如下:

    class Solution {
    public:
        ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
            if(!pListHead||k<=0)return nullptr;
            ListNode *pre,*last;
            pre=pListHead;
            last=pListHead;
            for(int i=1;i<k;i++){
                if(!pre->next) return nullptr;
                else pre=pre->next;
            }
            while(pre->next){
                pre=pre->next;
                last=last->next;
            }
            return last;
        }
    };
    
    keep going
  • 相关阅读:
    (译+原)std::shared_ptr及std::unique_ptr使用数组
    (转+原)ipp "No dlls were found in the Waterfall procedure"
    (原)vs2013编译boost1.60库
    (原+转)VS2013:正在从以下位置加载符号
    (原)直方图的相似性度量
    (原)Opencv中直方图均衡和图像动态范围拉伸的代码
    JAVA 8 新特性 Stream API 创建
    JAVA 8 新特性 Stream API 介绍
    JAVA 8 新特性 方法引用
    JAVA 8 新特性 函数式接口
  • 原文地址:https://www.cnblogs.com/MarkKobs-blog/p/10406837.html
Copyright © 2011-2022 走看看