- 题目描述
编写代码,移除未排序链表中的重复节点。保留最开始出现的节点。
示例1: 输入:[1, 2, 3, 3, 2, 1]
输出:[1, 2, 3]
示例2: 输入:[1, 1, 1, 1, 2]
输出:[1, 2] - 提示: 链表长度在[0, 20000]范围内。 链表元素在[0, 20000]范围内。
- 进阶:
如果不得使用临时缓冲区,该怎么解决? - 解题思路
- 思路一:定义两个指针current和p来逐个遍历链表,current元素依次和p比较,直到p为NULL,current向后移动一个。
- 代码实现
c
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
/*
函数主要是两层循环,外层循环实现遍历整个链表,内层循环负责遍历比较当前节点值与其后所有节点值,若相等则跳过,
*/
struct ListNode* removeDuplicateNodes(struct ListNode* head) {
// Return NULL if the list is empty
if (head == NULL) return NULL;
struct ListNode *current = head;
// Iterate through each node in the list
while (current) {
struct ListNode* p = current;
// Check subsequent nodes for duplicates
while (p->next) {
// If a duplicate is found, remove it
if (p->next->val == current->val) {
p->next = p->next->next;
} else {
// Otherwise, move to the next node
p = p->next;
}
}
// Move to the next node in the list
current = current->next;
}
// Return the modified list
return head;
}
- 问题记录
- 内层循环的结果是在哪保存的?
内层循环遍历current节点后的所有节点,发现有重复值时,就会改变节点的指向,即已经改变了链表结构。下一次遍历时,链表已经是改变后的链表了。
- 思路二:利用标记数组,标记当前值是否出现过。
c
struct ListNode* removeDuplicateNodes(struct ListNode* head){
if(head == NULL || head->next == NULL) return NULL;
int index[20001] = {0};
index[head->val] = 1;
struct ListNode *pre = head, *q = head->next;
while(q){
if(index[q->val] == 0){
index[q->val] = 1;
pre = q;
q = q->next;
}else{
pre->next = q->next;
q = pre->next;
}
}
return head;
}