【leetcode】面试题 02.01. 移除重复节点
编写代码,移除未排序链表中的重复节点。保留最开始出现的节点。
示例1:
输入:[1, 2, 3, 3, 2, 1]
输出:[1, 2, 3]
示例2:
输入:[1, 1, 1, 1, 2]
输出:[1, 2]
提示:
链表长度在[0, 20000]范围内。
链表元素在[0, 20000]范围内。
进阶:
如果不得使用临时缓冲区,该怎么解决?
解题思路:
若链表为空,直接返回空链表。
若链表不为空,则先定义occured数组,用来标记元素是否出现过,0表示未出现过,1表示出现过。然后遍历链表,若当前元素未出现过,标记为1,并移动指针位置,向后移动一位。若当前元素出现过,则跳过当前重复节点,指针直接指向下一个节点。
代码:
C:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeDuplicateNodes(struct ListNode* head){
if (head == NULL)// && head -> next == NULL
return head;
//calloc是stdlib.h库里的函数,分配内存,并全部初始化为0。申请20001个int类型的空间
//定义occured数组,用来标记元素是否出现过,0表示未出现过,1表示出现过
int* occured = (int*)calloc(20001, sizeof(int));
occured[head -> val] = 1; //head-val表示第一个元素的值
//head -> next -> val表示第二个元素的值
struct ListNode* pos = head;
while (pos -> next)
{
struct ListNode* cur = pos -> next;
if (occured[cur -> val] != 1) //若当前元素未出现过
{
occured[cur -> val] = 1; //标记为1
pos = pos -> next; //移动指针位置,向后移动一位
}
else
{
pos -> next = pos -> next -> next; //跳过重复节点,指针直接指向下一个节点
}
}
return head;
}
备注:
calloc和malloc的区别
calloc分配内存后,会将所有元素全部初始化为0,而malloc分配内存后,不会进行初始化操作。