Day46-链表绝对值结点删除

237 阅读1分钟

[2015统考真题]

用单链表保存m个整数,结点的结构为[data] [link],且data <=n(n为正整数。现要求设计一个时问复杂度尽可能高效的算法,对于链表中 data 的绝对值相等的结点,仅保留第一次出现的结点而删除其余绝对值相等的结点。例如,若给定的单链表 head 如下: 则删除结点后的 head 为下图

image.png

则删除结点后的 head 为 head

要求:

  1. 给出算法的基本设计思想。

2.使用采用C或C++语言描述算法给出单链表结点的数据类型定义

  1. 根据设计思想,采用C或C++语言描述算法,关键之外给出注释 说明你所设计算法的时间复杂度和空间算杂度

思路:

给出算法的基本设计思想。

算法的核心思想是用空间换时间。使用辅助数组记录链表中已出现的数值,从而只需要对链表进行一趟扫描; 因为|data|<=n,所以辅助数组q的大小为n+1,各元素的初始值均为0。

依次扫描链表中各结点,同时检查q[addr](addr=|data|)的值;如果q[addr]的值为0,则保留该结点,并令q[addr]的值为1;否则将该结点从链表中删除;

单链表节点的数据类型定义:

使用采用C或C++语言描述算法给出单链表结点的数据类型定义

typedef struct LNode{
    int data;
    struct LNode *link;
}LNode;

代码:

根据设计思想,采用C或C++语言描述算法,关键之外给出注释

static void del(ListNode head,int n) {
    ListNode pre = head;
    ListNode p = head.next;
    int m = 0;
    int[] arr = new int[n + 1];
    while ( p != null){
        m = p.value >= 0 ? p.value : -p.value;
        if (arr[m] == 0){
            arr[m] = 1;
            p = p.next;
            pre = pre.next;
        }else {
            pre.next = p.next;
            p = p.next;
        }
    }
}

时间复杂度:O(m);

空间复杂度:O(n);