其中L是用户传入的参数,L是带头结点单链表的头指针,输入案例1 2 3 3 3 4 5 6 7 8 - 1
输出为1 2 3 4 5 6 7 8
我可以解决该问题。
算法思路:
遍历链表,对于每个节点,遍历它后面的所有节点,如果值重复,则删除后面的节点。要注意,删除过节点之后,需要再次遍历被删除节点前面的节点,更新它们的 next 指针,指向删除节点之后的节点。
在链表中删除某个节点,需要知道该节点的前驱节点,因此需要使用双指针方法。
代码实现:
#include <iostream>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
ListNode* deleteDuplicates(ListNode* L) {
if (L == NULL || L->next == NULL) {
return L;
}
ListNode *p, *q, *tmp;
p = L->next; // p 指向第一个有可能被删除的节点
while (p != NULL) {
// q 指向 p 的前驱节点
q = L;
while (q->next != p) {
q = q->next;
}
tmp = p->next;
bool flag = false; // 标记是否有重复节点
while (tmp != NULL && tmp->val == p->val) {
tmp = tmp->next;
flag = true;
}
if (flag == true) {
q->next = tmp;
delete p;
p = tmp;
} else {
p = p->next;
}
}
return L;
}
int main() {
ListNode *L = new ListNode(-1);
ListNode *p = L;
int x;
do {
cin >> x;
if (x == -1) {
break;
}
ListNode *tmp = new ListNode(x);
p->next = tmp;
p = tmp;
} while (true);
L = deleteDuplicates(L);
p = L->next;
while (p != NULL) {
cout << p->val << " ";
p = p->next;
}
cout << endl;
return 0;
}
1