问题描述
分别实现两个方法,一个可以删除单链表中的倒数第k个节点,另一个可以删除双链表的倒数第k个节点
问题分析
- 先处理特殊的情况:k=0的时候,此时无法输出这样的节点
一般的考虑:
①遍历链表,k–;
在图片里可以看到:
临界值k=1,取最后一个节点,k–最后结果得到是-6;
临界值k=7,取第一个节点,k–最后结果得到0;
所以,遍历链表k,如果最后k的值是<=0的,那么可以正常取到这个节点。
②再次遍历链表。k++;
可以看到最后要取出来的节点对应的k值都会是1
所以在这次遍历过程中,只需要判断k,当k等于0的时候,下一个节点即是要删除的节点了。代码实现
package algorithm_zuochengyun; public class CH2_02_removeLastKthNode { public static Node removeLastKthNode(Node head, int k) { if (head == null || k < 1) { return head; } Node current = head; while (current != null) { current = current.next; k--; } if (k == 0) { // k是第一个node head = head.next; } else if (k < 0) { // k是中间的node current = head; while (++k != 0) { current = current.next; } current.next = current.next.next; } else { System.out.println("worong k input ."); } return head; } public static DoubleNode removeLastKthNode(DoubleNode head, int k) { if (k < 1 || head == null) { return head; } // 头结点的位置在不确定是不是删除头结点的情况下不能改动, // 需要用另外一个结点来代替他移动 DoubleNode current = head; while (current != null) { current = current.next; k--; } if (k == 0) { head = head.next; } else if (k < 0) { current = head; // 如果用K++则会导致 NullPointerException异常 while (++k != 0) { current = current.next; } head.next = head.next.next; } return head; } public static void main(String[] args) { // TODO Auto-generated method stub Node head1 = Node.init(); Node.Print(head1); Node.Print(removeLastKthNode(head1, 3)); System.out.println(); DoubleNode head2 = DoubleNode.init(); DoubleNode.PrintNext(head2); DoubleNode.PrintNext(removeLastKthNode(head2, 3)); } }
实现结果
问题总结
假设链表长度为n,需要取出倒数第k个,第一次遍历到头最后k=k-n,第二次遍历,当遍历到k=0的时候就是要删除的节点了。