链表中倒数第k个结点
题目:输入一个链表,输出该链表中倒数第k个结点。
给定的链表节点:
class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } }
一开始我的想法是,先定义一个长度为k的ListNode数组,然后遍历一遍链表的所有节点,并把每个节点循环存到这个数组里面。“循环存”就是当数组存满的时候,返回到数组第0个位置开始覆盖存储,最后从倒数第一个逆推到倒数第k个。
代码如下:
public ListNode FindKthToTail(ListNode head,int k) { ListNode[] listNodes = new ListNode[k]; int index = -1; int count = 0; if (head == null || k == 0) return null; while (head != null) { index = (index + 1) % k; listNodes[index] = head; head = head.next; count++; } if (k > count) return null; //k大于链表结点的个数时 //从倒数第一个往回推 count = 1; while (count < k) { index = index - 1 >= 0 ? index -1 : index - 1 + k; count++; } return listNodes[index]; }
后面看了别人的解法的时候,发现这样做有点无脑。
第二个做法是,定义两个结点(如first, second)指向头结点,其中一个结点(first)先向前移动到第k个结点,这个时候正数的话second是在第一个位置,而first是在第k个位置。然后将两个结点同时移动,知道first到达最后一个结点,此时second刚好到达倒数第k个结点。
代码如下:
public ListNode FindKthToTail2(ListNode head,int k) { ListNode first = head; ListNode second = head; if (head == null || k == 0) return null; for (int i=1; i<k; i++) { first = first.next; if (first == null) return null; //k大于整个链表的长度 } while (first.next != null) { first = first.next; second = second.next; } return second; }