数据结构与算法-链表
刷题练习
删除链表的倒数第 n 个元素
输入链表为:5->4->3->2->1 ,3
输出链表为:5->4->2->1
#include <QCoreApplication>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct Node
{
int m_nValue;
Node* m_pNext;
Node(int nValue, Node* pNext = nullptr) : m_nValue(nValue), m_pNext(pNext)
{
// ...
}
};
class Solution
{
public:
// 删除链表倒数第 n 个元素
static Node* RemoveBackNth(Node* pHead, int n)
{
Node* pDummyHead = new Node(0, pHead);
Node* pFast = pDummyHead;
Node* pSlow = pDummyHead;
// 让快指针指向第 n 个元素位置
while (n > 0 && nullptr != pFast)
{
pFast = pFast->m_pNext;
--n;
}
// 如果链表本身的长度不够 n , 或者 n 的值不合理
if (0 != n || nullptr == pFast)
{
delete pDummyHead;
return pHead;
}
// 要删除的目标元素的位置是哪个
// 倒数第 1 ---> L - 1 + 1
// 倒数第 2 ---> L - 2 + 1
// 倒数第 n ---> L - n + 1
// 目标位置为 L - n + 1,我们让 pSlow指向 L - n位置
// 需要移动 L - n 次
// pFast 从 n 到 L 需要 L - n 次
while (nullptr != pFast->m_pNext)
{
pFast = pFast->m_pNext;
pSlow = pSlow->m_pNext;
}
// 此时 pFast 指向的是 L , pSlow指向的是 L - n
Node* pDelete = pSlow->m_pNext;
pSlow->m_pNext = pSlow->m_pNext->m_pNext;
pHead = pDummyHead->m_pNext;
// 进行堆内存的释放
delete pDelete;
delete pDummyHead;
return pHead;
}
// 创建链表
static Node* CreateList(const vector<int>& vecData)
{
if (vecData.empty())
return nullptr;
Node* pHead = new Node(vecData[0]);
Node* pCur = pHead;
for (size_t i = 1; i != vecData.size(); ++i)
{
pCur->m_pNext = new Node(vecData[i]);
pCur = pCur->m_pNext;
}
return pHead;
}
// 打印链表
static void PrintList(Node* pHead)
{
cout << "List Data : [ ";
Node* pCur = pHead;
while(nullptr != pCur)
{
if (nullptr != pCur->m_pNext)
{
cout << pCur->m_nValue << ", ";
}
else
{
cout << pCur->m_nValue << " ]\n";
return;
}
pCur = pCur->m_pNext;
}
cout << " ]\n";
}
static void Test()
{
vector<int> vecData = { 5, 4, 3, 2, 1 };
Node* pHead = CreateList(vecData);
PrintList(pHead);
pHead = RemoveBackNth(pHead, 3);
PrintList(pHead);
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Solution::Test();
return a.exec();
}