這類題的常見思路是設置兩個指針,開始都指向頭結點,第一個指針走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;
}
};