输入一个链表,输出该链表中倒数第k个结点。
最简单的思路:两次遍历,第一次获取链表长度n,第二次遍历n-k+1步即可。
只遍历一遍:定义两个指针,第一个指针走k-1步,第二个不动,从第k步开始,两个指针同时遍历,当第一个走到链表尾节点,第二个指针正好指向倒数第k个节点。
代码:
/**
* @author yuan
* @date 2019/2/12
* @description
*/
public class 链表中倒数第k个节点 {
static class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
public ListNode FindKthToTail(ListNode head, int k) {
if (head == null || k == 0) {
return null;
}
ListNode p = head;
for (int i = 0; i < k - 1; i++) {
if (head.next != null) {
head = head.next;
} else {
// 如果链表没有k-1个节点
return null;
}
}
while (head.next != null) {
head = head.next;
p = p.next;
}
return p;
}
}
leetcode 删除链表的倒数第N个节点
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:
给定的 n 保证是有效的。
前面p节点就是倒数的第n个节点,删除p即可。
要删除一个节点有两种方法:
- 得到被删除节点的前一个节点,将前一个节点指向被删除的下一个节点。
- 不需要获取被删除的前一个节点,将被删除节点的下一个的内容复制到被删除节点,然后删除被删除节点的下一个节点。
具体看代码:
/**
* @author yuan
* @date 2019/2/12
* @description
*/
public class 删除链表的倒数第N个节点 {
static class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
public ListNode removeNthFromEnd(ListNode head, int n) {
// 删除第0个节点不合法、如果只有一个节点,删除后为null
if (head == null || n == 0 || head.next == null) {
return null;
}
ListNode p = head, pHead = head;
for (int i = 0; i < n - 1; i++) {
if (head.next != null) {
head = head.next;
} else {
// 如果链表没有k-1个节点
return null;
}
}
ListNode q = p;
// 如果是删除第一个节点
if (head.next == null) {
return p.next;
}
while (head.next != null) {
head = head.next;
q = p;
p = p.next;
}
// p为要删除的节点,q指向p的前一个节点
q.next = p.next;
return pHead;
}
}