• 剑指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
  • 相关阅读:
    android 自定义日历控件
    android 常用类
    真假空格风波
    设计模式的初衷---“委托”有感
    pymysql.err.InterfaceError: (0, '')
    微信文章收藏到有道云笔记PC版只保留了标题
    SQL Server数据库字典生成SQL
    nhibernate常见错误
    NUnit
    使用ffmpeg截取视频
  • 原文地址:https://www.cnblogs.com/MarkKobs-blog/p/10406837.html
Copyright © 2020-2023  润新知