- 题目
2. 题解
2.1 题解1: 一次循环直接新生成新的链表
题解思想:首先新建一个头结点,然后循环查找链表,如果找到不相等的元素地址,链接到头结点上面,以此循环;
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* }; */
struct ListNode* deleteDuplicates(struct ListNode* head){
struct ListNode newHead = {0}; // 申请一个new头结点
if (!head || !head->next) return head; // 头结点为空或只有一个节点,直接返回head;
struct ListNode *i = head, *j;
struct ListNode *tail = &newHead;
while (i && i->next) {
for (j = i->next; j; j = j->next) {
if (i->val != j->val) {
if (j == i->next) {
tail->next = i;
tail = i;
tail->next = NULL;
}
break;
}
}
i = j;
}
if (i) tail->next = i;
return newHead.next;
}
2.2 题解2: 直接删除(递归)
题解思想:遇到相同的元素后,采用递归法得到这个相同元素后的第一个不同元素的地址,将pre->next赋值给它,也就是删除期间相同的元素,返回结果为第一个pre的有效地址,如果pre无效,则返回cur地址;
struct ListNode* findNewHead(struct ListNode* cur) {
if (cur->next == NULL) { return cur; }
if (cur->val != cur->next->val) { return cur; }
return findNewHead(cur->next);
}
struct ListNode* deleteDuplicates(struct ListNode* head){
struct ListNode *cur = head;
struct ListNode *pre = NULL;
struct ListNode *newHead = head;
struct ListNode *result = head;
int cnt = 0;
/*如果为空或者只有一个结点直接返回*/
if ((head == NULL) || (head->next == NULL)) {
return head;
}
while (cur != NULL) {
if ((cur->next != NULL) && (cur->val == cur->next->val)) {
newHead = findNewHead(cur);
newHead = newHead->next;
cur = newHead;
if (pre) { pre->next = cur; }
} else {
pre = cur;
cur = cur->next;
if (cnt == 0) {
result = pre;
cnt++;
}
}
}
/* [1,1,2]*/
if (cnt == 0) { result = cur; }
return result;
}