题目描述
输入一个链表,输出该链表中倒数第k个结点
分析:方法一:遍历两次链表,第一个统计出链表的节点的个数(例如n个),第二次就遍历到第n-k个节点,就是倒数第k个节点。这种方法要遍历两次链表。
方法二:定义两个指针,第一个指针从链表头开始先走k-1步,然后两个指针同时向前走,当走的快的指针到达链表末尾最后一个节点时,慢的指针指向倒数第k个节点。
方法二的代码实现:
public class Solution{ public ListNode FindKthToTail(ListNode head,int k){ if(head==null||k<=0) return null; ListNode p = head; int i = 1; while(i<k&&p!=null){ p = p.next; i++; } if(p==null) //如果k大于链表节点的个数 return null; ListNode q = head; while(p.next!=null){ //p和q之间举例了k-1个节点 q = q.next; p = p.next; } return q; } }
说明:这个题目的考点除了想到使用两个指针来一次遍历链表找到倒数第k个节点外,还要注意特殊用例:
1)输入的头指针为空指针,此时直接返回
2)输入的k为0,此时返回null
3)如果k大于链表的个数,此时返回null
ListNode p = head; int i = 1; while(i<k&&p!=null){ p = p.next; i++; } if(p==null) //如果k大于链表节点的个数 return null;如果k大于链表的个数,此时p=null会退出while循环,这时通过if(p==null)判断后输出为空。
类比:在链表的插入时,例如在第i个节点插入时,我们也要先定位到第i-1个节点,这里也有刚刚所说的几个条件的判断,例如链表中有四个元素,我们想在第6个元素前插入,此时也要进行相应的处理。
//在第i个节点前插入节点 /* 注意一:此时定位到第i-1个节点 注意二:现在没有头结点的情况,所以在第一个节点前插入有点特殊 */ public void ListInsert(int i,Item item){//在第i个节点前插入节点 Node<Item> p = head; int k = 2; while(k<i&&p!=null){ //定位到i-1个节点 p = p.next; k++; } if(p==null&&i!=1) //如果i>k+1此时,直接返回null return; Node<Item> q = new Node<>(item); if(i==1){ //插入在第一节点前插入操作有点特殊 q.next = head; head = q; } else{ q.next= p.next; p.next = q; } }
扫描二维码关注公众号,回复:
1739022 查看本文章