链表中倒数第K个结点19.9.23

目录

题目描述

题解

第一种

第二种

第三种


题目描述

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

题解

第一种

这题有很多的想法,我最初想到的是先获取链表的长度,然后根据前后的关系,从前往后遍历,遍历到指定点时,返回该结点。代码如下:

/*
public class ListNode {
    int val;
    ListNode next = null;
    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode FindKthToTail(ListNode head,int k) {
        int length = getLength(head);
        ListNode l1 = head;
        int count=0;
        while(l1!=null){
            if(count == length-k){ //到达指定节点
                return l1;
            }
            count++;
            l1 = l1.next;
        }
        return l1;
    }//获取链表长度
    public int getLength(ListNode head){
        ListNode cur = new ListNode(0);
        cur = head;
        int count=0;
        while(cur!=null){
            count++;
            cur = cur.next;
        }
        return count;
    }
}

 

第二种

用栈来存储,然后反向弹出并计数,这时候要注意的是,栈中记录的是每个节点,即地址,这样返回的时候直接返回弹出的这个值。

/*
public class ListNode {
    int val;
    ListNode next = null;


    ListNode(int val) {
        this.val = val;
    }
}*/
import java.util.Stack; //不要忘记头文件哦
public class Solution {
    public ListNode FindKthToTail(ListNode head,int k) {
        if(head == null || k<=0)
            return null;
        ListNode list = head;
        //借助栈的结构,保存链表结点的地址
        Stack<ListNode> stack = new Stack<ListNode>();
        int count = 1;
        //全部入栈
        while(head!=null){
            stack.push(head);
            head = head.next;
        }
        //判断
        while(!stack.isEmpty()){
            if(count != k){
               stack.pop();
               count++;
            }
            else if(count == k)
                return list = stack.pop();
        }
        //为空,说明越界了
        return null;
    }
}

加上栈的结构,其时间复杂度和空间复杂度都是会有所增加

第三种

       看了解题的讨论,由衷感觉比较巧妙的解法,可以用两个指针来实现,意思是这样的:有两个指针slow,fast初始都指向头指针head 。 slow先不动,fast先跑k-1个结点,然后两个一起开始跑,当fast到最后一个结点的时候,slow指针所在的位置就是倒数第K个结点。而且这样的时间复杂度只有O(N),且额外空间复杂度为O(1),比前两种要好!!!

时间复杂度O(n),一次遍历即可
public class Solution {
    public ListNode FindKthToTail(ListNode head,int k) {
        ListNode pre=null,p=null;
        //两个指针都指向头结点
        p=head;
        pre=head;
        //记录k值
        int a=k;
        //记录节点的个数
        int count=0;
        //p指针先跑,并且记录节点数,当p指针跑了k-1个节点后,pre指针开始跑,这时两者一起跑
        //当p指针跑到最后时,pre所指指针就是倒数第k个节点
        while(p!=null){
            p=p.next;
            count++;
            if(k<1){
                pre=pre.next;
            }
            k--;
        }
        //如果节点个数小于所求的倒数第k个节点,则返回空
        if(count<a) return null;
        return pre;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值