JAVA实现链表中倒数第K个节点问题(《剑指offer》)(考虑问题要全面)

来源:互联网 发布:旋风磁力数据接口 编辑:程序博客网 时间:2024/05/18 03:48

题目描述

输入一个链表,输出该链表中倒数第k个结点。
解题思路:
两个指针,先让第一个指针和第二个指针都指向头结点,然后再让第一个指正走(k-1)步,到达第k个节点。然后两个指针同时往后移动,当第一个结点到达末尾的时候,第二个结点所在位置就是倒数第k个节点。

本题收获:考虑问题要全面,保持代码的鲁棒性(健壮性)。

提高代码的鲁棒性的有效途径是进行防御性编程。

防御性编程 是 一种编程习惯,是指预见在什么地方可能会出现问题,并为这些可能出现的问题制定处理方式。

本题需要考虑的注意事项:

1、考虑传入的头指针为NULL;

2、考虑链表结点总数 少于 k;

3、考虑输入的 k 值小于等于0;

这三点一定要考虑,防止潜在的崩溃风险。


解答:
[java] view plain copy
  1. /* 
  2. public class ListNode { 
  3.     int val; 
  4.     ListNode next = null; 
  5.  
  6.     ListNode(int val) { 
  7.         this.val = val; 
  8.     } 
  9. }*/  
  10. public class Solution {  
  11.     public ListNode FindKthToTail(ListNode head,int k) {  
  12.            if(head==null||k<=0){  
  13.             return null;  
  14.         }  
  15.          
  16.         ListNode last=head;         
  17.         for(int i=1;i<k;i++){  
  18.             if(head.next!=null){  
  19.                 head=head.next;  
  20.             }else{  
  21.                 return null;  
  22.             }  
  23.         }  
  24.         while(head.next!=null){  
  25.             head = head.next;  
  26.             last=last.next;  
  27.         }  
  28.         return last;  
  29.           
  30.     }  
  31. }  

相关题目,可做思考:

1、求链表的中间结点。如果链表中结点总数为奇数,返回中间结点;若结点总数是偶数,返回中间结点的任意一个。

为了解决这个问题,我们可以定义两个指针,同时从链表的头结点出发,一个指针一次走一步,另一个指针一次走两步。当走的快的指针走到链表的末尾时,走的慢的指针正好在链表的中间。

2、判断一个单向链表是否形成了环形结构。

和前面的问题一样,定义两个指针,同时从链表的头结点出发,一个指针一次走一步,另一个指针一次走两步。如果走得快的指针追上了走得慢的指针,那么链表就是环形链表;如果走得快得指针走到了链表的末尾(即pNext->NULL)都没有追上第一个指针,那么链表就不是环形链表。

通过这两个相关题目的解决思路,可以看出当我们用一个指针遍历链表不能解决问题时,可以尝试用两个指针来遍历链表,一个走得快些,另一个慢些。

因此对于本题,寻找倒数第k个结点,也可以这样做:

定义两个指针,第一个指针从链表的头指针开始遍历向前走 k-1,第二个指针保持不动,从第 k 步开始,第二个指针也开始从链表的头指针开始遍历。由于两个指针的距离保持在 k-1,当第一个(走在前面的)指针到达链表的尾结点时,第二个指针(走在后面的)指针正好是倒数第 k 个结点。


1 0
原创粉丝点击