链表中绝对值相等的节点,仅保留第一次出现的节点而删除其余绝对值相等的节点

题目:
用单链表保存m个整数,节点的结构为【data,link】,且|data|<n(n为正整数)。
现要求设计一个时间复杂度尽可能高效地算法,对于链表中绝对值相等的节点,仅保留第一次出现的节点而删除其余绝对值相等的节点。
例如,若给定的单链表head如下 :
在这里插入图片描述则删除节点后的head为:
在这里插入图片描述要求:

(1) 给出算法的基本思想

(2) 使用c或c++语言,给出单链表节点的数据类型定义。

(3) 根据设计思想,采用c或c++语言描述算法,关键之处给出注释。

(4) 说明所涉及算法的时间复杂度和空间复杂度。

基本设计思想:

  1. 算法的核心思想是用空间换时间。使用辅助数组记录链表中已出现的数值,从而只需要对链表进行一趟扫描;
  2. 因为|data|<=n,所以辅助数组q的大小为n+1,各元素的初始值均为0。
  3. 依次扫描链表中各结点,同时检查q[addr](addr=|data|)的值;如果q[addr]的值为0,则保留该结点,并令q[addr]的值为1;否则将该结点从链表中删除;

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

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

代码:

void simplify_list(LinkList &head,int n){
    //申请n+1个位置的辅助数组;
    q = (int *)malloc(sizeof(int)*(n+1));
    for(int i=0;i<n+1;i++){//数组元素初值设为0;
        q[i] = 0;
    }
    
    LNode *p = head->link;
    pre = head;
    while(p !=NULL){
        int data = p->data;
        int addr = data >0? data:-data;
        
        if(q[addr] ==1){//需要删除当前节点p
            temp = p;
            pre->link = p->link;
            p=p->link;
            free(temp);
        }else{//保留当前节点;
            q[addr] =1;
            pre = p;
            p = p->link;
        }  
    }
	free(q);  //释放辅助空间;
}

时间复杂度:O(m);

空间复杂度:O(n);

  • 4
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值