[2015统考真题]
用单链表保存m个整数,结点的结构为[data] [link],且data <=n(n为正整数。现要求设计一个时问复杂度尽可能高效的算法,对于链表中 data 的绝对值相等的结点,仅保留第一次出现的结点而删除其余绝对值相等的结点。例如,若给定的单链表 head 如下: 则删除结点后的 head 为下图
则删除结点后的 head 为 head
要求:
- 给出算法的基本设计思想。
2.使用采用C或C++语言描述算法给出单链表结点的数据类型定义
- 根据设计思想,采用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);