这类题的常见思路是设置两个指针,开始都指向头结点,第一个指针走K步后第二个指针再开始走,因为两个指针中间隔着K步,所以,当第一个指针指向最后一个NULL时,第二个指针刚好指向链表倒数第K个元素。除了思路是关键点外,这类题的鲁棒性是面试官考察的重点,具体是:1.输入的n比整个链表还长;2.n=0;3.链表为空。这三点要处理好。
一.在链表中查找倒数第K个元素
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
ListNode* head1 = pListHead;
if(pListHead == NULL)
return NULL;
int i;
for(i = 0; i < k && head1 != NULL; i ++){
head1 = head1 -> next;
}
if(head1 == NULL && i < k)//不存在倒数第k个元素
return NULL;
if(head1 == NULL && i == k)//第一个元素是第k个元素
return pListHead;
ListNode* temp = pListHead;
while(head1){
head1 = head1 -> next;
temp = temp -> next;
}
return temp;
}
};
二.在链表中删除倒数第K个元素
删除与查找倒数第K个元素的区别是查找需要定位到正好第K个元素,而删除需要定位到第K个元素的前一个元素。因此,对于查找,两个指针要相隔K个元素,而对于删除,两个元素要相隔k+1个元素.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* head1 = head;
int i;
for(i = 0; i <= n && head1 != NULL; i ++){
head1 = head1 -> next;
}
if(head1 == NULL && i < n)//不存在倒数第n个元素
return head;
if(head1 == NULL && i == n)//第一个元素是第n个元素
return head -> next;
ListNode* temp = head;
while(head1){
head1 = head1 -> next;
temp = temp -> next;
}
temp -> next = temp -> next -> next;
return head;
}
};