删除链表中倒数第n个节点
/**
* 方法
* 1.哈希表
* 2.栈:倒着计算的问题,优先想到,边界条件烦人
* 3.暴力法:求长度
* 4.双指针(快慢指针,初始条件,移动策略,边界判断)
* 5.翻转链表
* @param head
* @param n
* @return
*/
//栈,时间复杂度,O(n),空间复杂度:O(N)
ListNode* removeNthFromEnd1(ListNode* head, int n) {
stack<ListNode*> st;
//边界条件
if (head == nullptr)
return nullptr;
ListNode* temp = head;
//计数器,用来倒着计数的
int count = 1;
while (temp != nullptr){
st.push(temp);
temp = temp->next;
}
while (!st.empty()){
ListNode* temp = st.top();
st.pop();
if (count == n)
{
//特殊情况
if (st.empty()){
head = temp->next;
break;
}
st.top()->next = temp->next == nullptr? nullptr:temp->next;
delete temp;
break;
}
count++;
}
return head;
}
//快慢指针
ListNode* removeNthFromEnd(ListNode* head, int n){
//边界条件
if (head == nullptr)
return head;
//快慢指针初始条件
ListNode* first = head;
ListNode* second = head;
//快指针先移动n个位置
for (int i = 0; i < n; ++i) {
first = first->next;
}
//first为空的时候,表示删除的是头节点
if (first == nullptr){
head = head->next;
return head;
}
//当快指针为空时,进行节点删除,或者secon == nullptr
while (first->next != nullptr){
first = first->next;
second = second->next;
}
// 删除节点
ListNode* temp = second->next;
// 判断second和first是否相邻,相邻的话删除first
second->next = (temp == first? nullptr:temp->next);
delete temp;
return head;
}