核心思想
  • 设置前哨结点和移动前哨结点指针
  • 一次遍历,判断当前指针和下一个指针相等,就删除下一个结点,直到下一个不相等值
    • 有重复的,删除之际,标记出来当前结点需要删掉
  • 判断标记,当前结点是否需要删掉
  • 遍历完后,需要注意最后的当前结点是否需要删除
/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 */
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param head ListNode类 
 * @return ListNode类
 */
struct ListNode* deleteDuplicates(struct ListNode* head ) {
    // write code here
    // case1: null 
    if(head == NULL)
    {
        return head;
    }
    
    struct ListNode newHead = {0};
    (&newHead)->next = head;
    struct ListNode * move = head;
    struct ListNode * pre = (&newHead);
    
    int is_delete = 0;
    while(move->next != NULL)
    {
        if(move->val == move->next->val)
        {
            is_delete = 1;
            move->next = move->next->next;
            continue;
        }
        if(is_delete == 1)
        {
            pre->next = move->next;
            move = pre->next;
            is_delete = 0;
            continue;
        }
        pre = move;
        move = move->next;
    }
    
    if(is_delete == 1)
    {
        pre->next = NULL;
    }
    
    return (&newHead)->next;
}