题目
输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如,一个链表有6个节点,从头节点开始,它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个节点是值为4的节点。
我的解法:
看了题解,我这种解法是双指针。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode q=head;
ListNode res=head;
for(int i=0;i<k;i++){
q=q.next;
}
while(q!=null){
q=q.next;
res=res.next;
}
return res;
}
}
解法一:栈
这题要求的是返回后面的k个节点,我们只要把原链表的结点全部压栈,然后再把栈中最上面的k个节点出栈,出栈的结点重新串成一个新的链表即可
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
Stack<ListNode> stack = new Stack<>();
//链表节点压栈
while (head != null) {
stack.push(head);
head = head.next;
}
//在出栈串成新的链表
ListNode firstNode = stack.pop();
while (--k > 0) {
ListNode temp = stack.pop();
temp.next = firstNode;
firstNode = temp;
}
return firstNode;
}
}
解法二:递归
首先递归触底反弹的条件是head==null,所以会一直把指针传递到列表最后。
然后开始返回,当size==k的时候把node返回,之后就一直返回node即可。在size小于k的时候node都为空,size==k的时候node等于结果值,之后就一直返回这个结果值就好了。
//全局变量,记录递归往回走的时候访问的结点数量
int size;
public ListNode getKthFromEnd(ListNode head, int k) {
//边界条件判断
if (head == null)
return head;
ListNode node = getKthFromEnd(head.next, k);
++size;
//从后面数结点数小于k,返回空
if (size < k) {
return null;
} else if (size == k) {
//从后面数访问结点等于k,直接返回传递的结点k即可
return head;
} else {
//从后面数访问的结点大于k,说明我们已经找到了,
//直接返回node即可
return node;
}
}
化简之后:
class Solution {
int size;
public ListNode getKthFromEnd(ListNode head, int k) {
if (head == null)
return head;
ListNode node = getKthFromEnd(head.next, k);
if (++size == k)
return head;
return node;
}
}
总感觉看完这个解析之后就有点理解递归了!开心!