【2.5】
【题目大意】去掉链表中绝对值重复过的数字(只保留第一个)
【解法】删除的时候用当前枚举到的节点的前一个节点,这样的话能够方便删除。用数组来判重。
【代码】
int flag[10000+10];
void quchong(LNode *L){
LNode *p = L;
while (p->next!=NULL){
int t = p->next->data;
if (t<0) t = -t;
if (flag[t]==0){
flag[t] = 1;
p = p->next;
}else{
LNode *temp = p->next;
p->next = temp->next;
free(temp);
}
}
}
【2.6】
【题目大意】让你把两个有序链表合并成一个有序链表
【做法】就按照归并排序的思路合并就ojbk了,合并的时候把合并后的结果接在第一个链表的头结点后面就好!
【代码】
//合并之后,放到第一个链表里面
void _merge(LNode *h1,LNode *h2){
LNode *p1 = h1->next;LNode *p2 = h2->next,*t;
h1->next = NULL;
t = h1;
while (p1!=NULL && p2!=NULL){
if (p1->data<p2->data){
t->next = p1;
t = p1;
p1 = p1->next;
}else{
t->next = p2;
t = p2;
p2 = p2->next;
}
}
while (p1!=NULL) {
t->next = p1;t = p1;
p1=p1->next;
}
while (p2!=NULL){
t->next = p2;t = p2;
p2 = p2->next;
}
}
【2.7】
【题目大意】一个升序一个逆序的链表,让你合并成一个有序的单链表。
【做法】把逆序的那个原地倒置就好
//先把第二个链表原地倒置 然后当成2.6的合并做就好
void _merge(LNode *h1,LNode *h2){
LNode *p = h2->next;
h2->next = NULL;
while (p){
LNode * temp = p->next;
p->next = h2->next;
h2->next = p;
p = temp;
}
LNode *p1 = h1->next;LNode *p2 = h2->next,*t;
h1->next = NULL;
t = h1;
while (p1!=NULL && p2!=NULL){
if (p1->data<p2->data){
t->next = p1;
t = p1;
p1 = p1->next;
}else{
t->next = p2;
t = p2;
p2 = p2->next;
}
}
while (p1!=NULL) {
t->next = p1;t = p1;
p1=p1->next;
}
while (p2!=NULL){
t->next = p2;t = p2;
p2 = p2->next;
}
}
【2.8】同【2.6】代码
【2.9】
【题目大意】
无头结点的单链表两个
两个都是有序的
让你把这两个单链表合并成一个链表。
要求不能破坏第二个链表的结构
【做法】
在做归并的时候,如果第一个等于第二个,那么就跳过第二个链表遍历到的元素,这样第一个链表上有的元素,第二个链表里对应的就不会管他了。
无头结点不好直接在h1的基础上添加新的元素,所以自己另外创建一个无头结点的链表.一个一个累加上去就好。
【代码】
//这里必须要用二重指针,因为我们要改变第一个链表的指向(我们新创的一个链表)
//main函数里调用_merge(&h1,h2)即可(h2不用变)
void _merge(LNode **h1,LNode *h2){
LNode *p1 = *h1;LNode *p2 = h2,*h3;
h3 = newnode();//不好直接接在第一个链表上,所以新创建一个
LNode *t = newnode();
t = h3;
while (p1!=NULL && p2!=NULL){
if (p1->data<p2->data){
LNode *temp = newnode(); //不能破坏原始链表,所以只能自己创了
temp->data = p1->data;
t->next = temp;
t = temp;
p1 = p1->next;
}else if (p1->data>p2->data){
LNode *temp = newnode();
temp->data = p2->data;
t->next = temp;
t = temp;
p2 = p2->next;
}else if (p1->data==p2->data){
//如果两个链表中有,那么只要第一个链表中的
p2 = p2->next;
}
}
if (p1==NULL) p1 = p2; //这样写比较简洁
while (p1!=NULL) {
LNode *temp = newnode();
temp->data = p1->data;
t->next = temp;t = temp;
p1=p1->next;
}
*h1 = h3->next;//让h1再指向h3
}
【2.10】和【2.9的代码一样】只不过变成带头结点的了。遍历到两个链表的p和q的时候,如果p->data==q->data,则跳过其中一个就好了。
因为是集合,所以只会重复一次。
【2.11】
【题目大意】
求两个集合的交集(在两个链表里递增排列),
【做法】
也没说带不带头结点。。。就当做是有头结点吧。放在A链表中,这个简单,重构下A链表就好。
在归并的时候,如果p和q节点的节点值相同,就加到A链表的后面就好
【代码】
void _merge(LNode *h1,LNode *h2){
LNode *p1 = h1->next;LNode *p2 = h2->next,*t;
h1->next = NULL;
t = h1;
while (p1!=NULL && p2!=NULL){
if (p1->data<p2->data){
p1 = p1->next;
}else if (p1->data>p2->data){
p2 = p2->next;
}else if (p1->data==p2->data){
//如果两个链表中有,任取一个放在newA链表后面
t->next = p1;
t = p1;
p1 = p1->next;
}
}
}
【2.12】和【2.11】一样的。
【2.13】也一样。。
【2.14】
题目大意:给你三个递增链表A,B,C让你求A∪(B∩C),时间复杂度要求为O(|A|+|B|+|C|)