今天你如约而至了吗?互相监督,互相学习哦~上题:
题目描述
输入一个链表,输出该链表中倒数第k个结点。
分析:链表相比于数组,增删快,但是查询慢。需要查询链表中的哪个数时,每次都需要从头节点开始遍历。
这道题其实就是遍历找倒数第k个节点。两种方法:
方法一:倒数第k个节点,也就是正数length-k个节点;
1、先遍历链表,求得链表长度length;
2、从头开始遍历,找到链表中第length-k个节点。
方法二:快慢指针。
1、最开始设置两个指针慢指针和快指针,均赋值为head;
2、慢指针不同,快指针向前走k步;
3、此时快慢指针一起走,知道快指针走到最后一个,结束。
方法一:
代码:
/*
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 cur=head;
int len=0;
int i=0;
while(cur!=null){ //求解出链表的长度;
cur=cur.next;
len++;
}
if(len<k){ //如果链表长度小于k,输出null;
return null;
}
while(i<len-k){ //遍历链表,输出第len-k个节点;
pre=pre.next;
i++;
}
return pre;
}
}
牛客运行通过
运行时间:26ms
运行内存:9680Kb
这个方法很多人都能想到,一定要注意while循环链接的=取舍!!!
方法二:
代码:
/*
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 slow=head; //设置两个快慢指针,初始指向head
ListNode fast=head;
for(int i=0;i<k;i++){ //先让fast指针走k步;
if(fast==null){ //主要判断k有没有超过链表的长度。
return null;
}
fast=fast.next;
}
while(fast!=null){ //快慢指针一起走,知道走到最后;
slow=slow.next;
fast=fast.next;
}
return slow;
}
}
牛客运行通过
运行时间:24ms
运行内存:9640Kb
其实这种方法还是比较好理解的。
和第二种方法类似,用两个while循环实现;
代码:
/*
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 slow=head;
ListNode fast=head;
int i=1;
while(i<k){
if(fast.next==null){
return null;
}
fast=fast.next;
i++;
}
while(fast.next!=null){
slow=slow.next;
fast=fast.next;
}
return slow;
}
}
牛客运行通过
运行时间:30ms
运行内存:9552Kb
这个方法其实是我最一开始写的,但是一直报空指针异常,主要是自己在判断k和链表长度那里除了问题;
友情提示:
链表这个东西真的很绕,如果自己脑子里想不清楚,建议在纸上画个图或者写一下流程。
欢迎各位互相交流哦~~