题目描述
输入一个链表,输出该链表中倒数第k个结点。
题目格式
/* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } }*/ public class Solution { private int count = 0; private ListNode ret; public ListNode FindKthToTail(ListNode head,int k) { if(head == null) return null; FindKthToTail(head.next,k); count ++; if(count == k) ret = head; return ret; } }
解题思路一(比较懒的思路):
通过递归往回推的时候通过一个计数器不断递增,如果计数器等于k,那么我们就把这个节点保存下来。
源代码:
/* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } }*/ public class Solution { private int count = 0; private ListNode ret; public ListNode FindKthToTail(ListNode head,int k) { if(head == null) return null; FindKthToTail(head.next,k); count ++; if(count == k) ret = head; return ret; } }
这个代码并不是很好,因为为了保存这个节点,我还额外创建了实例变量,这样的编码也只能用于做题。
解题思路二(不使用递归):
比如说我们一共有5个元素,要求倒数第2个元素,那么其实就是正向的求第4个元素,也就是(5-2+1)个元素,那么我们的第一个元素就需要移动3次
但是对于链表我们无法知道它一开始有几个元素,所以可以用另外一种方法。
我们可以使用2个节点,我们可以利用后一个节点的移动的次数来决定前一个元素移动的次数。
还是上面这个例子。一共有5个元素(但一开始我们是不知道的),求倒数第2个元素
- 后面那个元素计算次数:只要我们从从整数第2个元素开始移动,移动到最后一个元素,那么就移动了3次,那么这样我们就可以计算出移动的次数啦
- 前面那个元素: 跟着移动就好了,停下来的时候就是倒数第二个元素了
- 考虑边界:如果k不大于0,或者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) { ListNode pre = head; ListNode post = head; if(head == null) return null; if(k <= 0) return null; //求出后一个节点该从第几个元素开始 for(int i = 0; i < k-1; i++) { post = post.next; if(post == null) return null; } while(post.next != null){ pre = pre.next; post = post.next; } return pre; } }