持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情
一、题目
struct ListNode {
int val;
ListNode *next = nullptr;
inline ListNode(int x, ListNode* next = nullptr) : val(x), next(next) { }
};
ListNode* removeRepeat(ListNode* pHead) {
}
int main(int, char**)
{
ListNode p1(1);
ListNode p2(2);
ListNode p3(3);
ListNode p4(3);
ListNode p5(4);
ListNode p6(4);
ListNode p7(5);
p1.next = &p2;
p2.next = &p3;
p3.next = &p4;
p4.next = &p5;
p5.next = &p6;
p6.next = &p7;
p7.next = nullptr;
ListNode* node = removeRepeat(&p1);
while(node){
cout << node->val << endl;
node = node->next;
}
return 0;
}
二、分析
根据题意可知
难点一:
需要获取链表中重复的节点
因为是单向链表,所以不能直接从右往左回溯,
这就造成要知道重复就得继续走,走了又回不来,
这个时候就只能遍历的时候同时判断当前节点和下一节点是否相等,
相等就继续走,把所有相等节点全部走完,
不相等就可以保留下来。
由于相等要继续走,不能单纯通过if来判断是否要保留,
所以需要一个状态量,记录此次遍历的结果。
容易忽略1:
假如最后一个有效节点后面有无效节点,还需要手动将有效节点的指向置空,因为它才是真正的尾节点
容易忽略2:
假如首节点是重复节点,首节点被过滤了之后就没有首节点了,所以还必须有一个新表头来放有效节点
三、实现
ListNode* removeRepeat(ListNode* pHead) {
if(pHead==nullptr || pHead->next==nullptr)return pHead;
ListNode result(0);
result.next = pHead;
ListNode* cur = &result;
bool repeat = false;
while(pHead){
while(pHead->next && pHead->val == pHead->next->val){
pHead = pHead->next;
repeat = true;
}
if(repeat){
repeat = false;
}else{
cur->next = pHead;
cur = pHead;
}
pHead = pHead->next;
}
cur->next = nullptr;
return result.next;
}
四、结言
这道题的关键在于细节的处理,有些很容易被忽视的点往往会造成解题一直无法通过,造成心理压力,从而恶性循环。
解题的时候要全面分析各种情况,才能无往而不利。
创作不易,留个赞再走吧!如果对文章内容有任何指正,欢迎评论!