出题:给定一个乱序链表,节点值为ASCII字符,但是其中有重复项,要求去除重复项并保证不改变剩余项的原有顺序;
分析:创建一个256(2^8)大小的bool数组,初始化为false,顺序读取链表,将字母对应位置为false的重新标记为true并保留节点,将字母对
应位置为true的保持并删除节点;时间复杂度为O(N),空间复杂度为常量。注意删除节点和不删除节点的情况下,pre和cur的移动操作不相同;
解题:
1 struct Node {
2 char value;
3 Node* next;
4 };
5 void DeleteDup(Node *head) {
6 if(head==NULL) {
7 printf("\nthe list is NULL");
8 return;
9 }
10
11 Node *pre=NULL, *cur=head;
12 /**
13 * 设置一个256的bool数组记录char是否
14 * 已经出现
15 * */
16 bool haveChar[256];
17 for(int i=0;i<256;i++)
18 haveChar[i]=false;
19 /**
20 * 如果haveChar对应为true,说明当前节点
21 * 的值已经出现过,则进行删除
22 * 如果haveChar对应为false,说明当前节点
23 * 的值第一次出现,则将其设置为true
24 * */
25 while(cur!=NULL) {
26 /**
27 * 注意删除节点的情况和不删除节点的情况
28 * pre和cur的需要不同的处理
29 * */
30 if(!haveChar[(cur->value)-‘0‘]) {
31 haveChar[(cur->value)-‘0‘]=true;
32 pre=cur;
33 cur=cur->next;
34 }
35 else {
36 pre->next=cur->next;
37 delete cur;
38 cur=pre->next;
39 }
40 }
41 }
42 int main() {
43 Node *a1=new Node();a1->value=‘a‘;
44 Node *a2=new Node();a2->value=‘d‘;
45 Node *a3=new Node();a3->value=‘s‘;
46 Node *a4=new Node();a4->value=‘d‘;
47
48 a1->next=a2;a2->next=a3;
49 a3->next=a4;a4->next=NULL;
50
51 DeleteDup(a1);
52
53 Node *temp=a1;
54 while(temp!=NULL) {
55 printf("\n%c",temp->value);
56 temp=temp->next;
57 }
58 return 0;
59 }
出题:给定两个已排序的数组,要求找出共同的元素;
分析:
- 如果两个数组大小接近,则分别使用指针first和second遍历两个序列,由于数组已经排序,所以遍历过的元素不会再次访问,所以时间复杂度为O(M+N);
- 如果两个数组大小差距较大,则在针对小数组中的每个元素在大数组中使用二分查找(每处理一个元素之后,大数组的范围都可以调整到上一个元素的后面),时间复杂度为O(NlogM),N足够小(M>N^2);
解题:
1 /**
2 * 时间复杂度O(M+N)
3 * */
4 void FindCommonInt1(int *first, int fl, int *second, int sl) {
5 int ft=0, st=0;
6 while (ft<fl && st<sl) {
7 if(first[ft]>second[st]) {
8 st++;
9 } else if(first[ft]<second[st]) {
10 ft++;
11 } else {
12 printf("\n%d",first[ft]);
13 ft++;st++;
14 }
15 }
16 }
17 /**
18 * 时间复杂度小于O(NlogM),其中M不断变小
19 * */
20 void FindCommonInt2(int *first, int fl, int *second, int sl) {
21 int start=0, end=fl-1;
22 int s,e,m;
23 for(int i=0;i<sl;i++) {
24 s=start;e=end;
25 while(s<=e) {
26 m=(s+e)/2;
27 if(first[m]>second[i]) {
28 e=m-1;
29 } else if(first[m]<second[i]) {
30 s=m+1;
31 } else {
32 printf("\n%d",first[m]);
33 start=m+1;
34 break;
35 }
36 }
37 }
38 }
39 int main() {
40 int first[]={1,2,3,4,5,6,10,11,12};
41 int second[]={1,4,9,10};
42 FindCommonInt2(first, 9, second, 4);
43 return 0;
44 }
时间: 2024-10-21 13:27:20