• 笔试算法题(28):删除乱序链表中的重复项 & 找出已经排好序的两个数组中的相同项


    出题:给定一个乱序链表,节点值为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("
    the 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("
    %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("
    %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("
    %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 }
  • 相关阅读:
    VC++学习(16):线程同步与异步套接字
    VC++学习(15):多线程
    VC++学习(12):文件操作
    VC++学习(10):绘图控制
    VC++学习(13):文档串行化
    VC++学习(11):图形的保存和重绘
    VC++学习(18):Active控件
    四大数据库的比较(SQL Server、Oracle、Sybase和DB2)
    Gridview中二级联动
    VS 2008中PDA开发环境的相关配置
  • 原文地址:https://www.cnblogs.com/leo-chen-2014/p/3747209.html
Copyright © 2020-2023  润新知