链表-重复值问题

作者: 茶还是咖啡 | 来源:发表于2020-03-05 08:14 被阅读0次

场景1

链表升序有序,去掉链表中重复的节点
eg:
1->1->2->3->3->4->5->5
结果
1->2->3->4->5

思路

  1. 每次判断尾指针和指针p的数据域是否相等,如果相等需要将指针p指向的节点删除,如图:



    删除后,重新赋值指针p的值,p = tail ->next


  2. 如果尾指针的值和指针p的数据域不一致,则两根指针都想后移动一个节点,然后重复上面的动作继续判断,直至指针p指向NULL



    从上面的描述中,可以看出全程直涉及“中间尾删”,不涉及“头删”,所以头指针的一直没有发生变化,所以函数的返回值为NULL即可。当然,也可以原样不动的返回头指针的地址。

code

void delRepeatNode(ElemSN *head){
    if(head==NULL){
        return;
    }
    ElemSN *tail = head, *p = tail->next;
    while (p!=NULL) {
        if(tail->data==p->data){
            tail->next = p->next;
            free(p);
            p = tail->next;
        }else{
            tail = p;
            p=p->next;
        }
    }
}

场景2

链表升序有序,去掉含有重复值的节点。
eg:
1->1->1->3->4->5->6->6
去重后:
3->4->5
这个题比较烧脑

  • 跟往常一样,使用两根指针q,p,如果发现这两个指针指向节点的数据域都是一样的,那么不仅要删除节点p,还要删除节点q,这意味着不仅p节点要有前驱指针,节点q也要有前驱指针,
  • 这里使用tail代表节点q的前驱指针。起始情况下,tail和q指向同一个节点。
  • 删除的节点可能是头结点,如本题需要删除的q节点即为头结点,所以要考虑头指针的指向是否需要变换。
  • 什么时候删除节点q?因为如果和节点p同时进行删除的话,那么如果链表中存在奇数个相同的节点,如图,那么我们无法判断第三个节点是不是重复节点,所有,不能马上删除节点q,要等到节点q和指针p指向节点不一致时,才进行删除节点q。

具体步骤如下:

  1. p,q节点的值相同,删除节点p


  2. 标记节点q是重复节点


  3. 继续删除节点p


  4. 节点p的值和q的值不一致了,是时候删除节点q了,如果q节点是头节点,进行头删,并更新头指针的指向。


  5. 没有重复的节点,指针整体向后移动


  6. 没有发现重复节点,指针整体向后移动


  7. 向后移动后,发现重复节点,但是需要删除的节点都是有前驱的,不虚!


code

ElemSN* delRepeatNode1(ElemSN *head){
    if (!head) {
        return NULL;
    }
    ElemSN *tail = head, *p = NULL, *q = NULL;
    p = head;
    while (p) {
        q = p;
        p = p->next;
        int flag = 0;
        while (p&&q->data == p->data) {
            flag = 1;
            q->next = p->next;
            free(p);
            p = q->next;
        }
        if (flag) {
            if (head == q) {
                head = head->next;
                if (head == tail->next) {
                    tail = head;
                }
            }
            else {
                tail->next = q->next;
            }
            free(q);
        }
        else {
            while (tail->next != p) {
                tail = tail->next;
            }
        }
    }
    return head;
}

相关文章

  • 链表-重复值问题

    场景1 链表升序有序,去掉链表中重复的节点eg:1->1->2->3->3->4->5->5结果1->2->3->...

  • 32.删除链表中重复的节点

    题目:链表是排序的,删除链表中值相同的所有节点,且不保留重复值的节点 思路:因为链表是排序的,重复值的节点肯定是相...

  • Swift - LeetCode - 删除链表中的节点

    题目 删除链表中等于给定值 val 的所有节点。 问题: 给定一个排序链表,删除所有重复的元素,使得每个元素只出现...

  • 删除链表中的重复节点

    题目:在一个排序的链表中,如何删除重复的节点? 思路:删除重复节点同样要考虑边界值的问题,头节点为重复,尾节点为重...

  • 删除链表中重复的结点(题号76)

    问题描述:在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。例如:链...

  • 重复值问题

    题目:Contains Duplicate Given an array of integers, find if...

  • LeetCode 817. Linked List Compon

    问题描述 给定一个链表的头指针 head,其中链表各节点值为互不相同的整数。同时给定一个列表 G,其值为链表所有值...

  • 面试题19-删除链表中重复的节点

    题目要求 删除链表中重复的节点。重复的节点:当前节点的值与下一个节点的值相等,那么称这两个节点为重复的节点 题目解...

  • 027-Remove Duplicates from Sorte

    描述 在一个排序单链表中,删除节点值重复出现的节点,保证每个节点的值只出现一次。 分析 单链表中可以访问到当前节点...

  • 《剑指offer》逆转链表

    问题: 输入一个链表,从尾到头打印链表每个节点的值。 实现方式: 双向链表 单项链表通过交换元素进行反转链表(我的...

网友评论

    本文标题:链表-重复值问题

    本文链接:https://www.haomeiwen.com/subject/efbmkhtx.html