王道面试P231

问题描述:

假如已知有n个人和m对好友关系(存于数字r)。如果两个人是直接或间接的好友(好友的好友的好友...),

则认为他们属于同一个朋友圈,

请写程序求出这n个人里一共有多少个朋友圈。

假如:n = 5, m = 3, r = {{1 , 2} , {2 , 3} ,{4 , 5}},表示有5个人,1和2是好友,2和3是好友,4和5是好友,

则1、2、3属于一个朋友圈,4、5属于另一个朋友圈,结果为2个朋友圈。

最后请分析所写代码的时间、空间复杂度。评分会参考代码的正确性和效率。

小米2013年招聘笔试算法题--朋友圈

[cpp] view plaincopy
  1. //朋友圈问题
  2. #include <iostream>
  3. using namespace std;
  4. int set[10001];
  5. //带路径优化的并查集查找算法
  6. inline int find(int x)
  7. {
  8. int i,j,r;
  9. r = x;
  10. while(set[r] != r)
  11. {
  12. r = set[r];
  13. }
  14. i = x;
  15. while(i != r)
  16. {
  17. j = set[i];
  18. set[i] = r;
  19. i = j;
  20. }
  21. return r;
  22. }
  23. //优化的并查集归并算法
  24. inline void merge(int x, int y)
  25. {
  26. int t = find(x);
  27. int h = find(y);
  28. if(t < h)
  29. {
  30. set[h] = t;
  31. }
  32. else
  33. {
  34. set[t] = h;
  35. }
  36. }
  37. int friends(int n , int m , int r[][2])
  38. {
  39. int i , count;
  40. //初始化并查集,各点为孤立点,分支数为n
  41. for(i = 1 ; i <= n ; ++i)
  42. {
  43. set[i] = i;
  44. }
  45. for(i = 0 ; i < m ; ++i)
  46. {
  47. merge(r[i][0] , r[i][1]);
  48. }
  49. for(i = 1 ; i <= n ; ++i)
  50. {
  51. cout << set[i] <<" ";
  52. }
  53. count = 0;
  54. for(i = 1 ; i <= n ; ++i)
  55. {
  56. if(set[i] == i)
  57. {
  58. ++count;
  59. }
  60. }
  61. return count;
  62. }
  63. void main()
  64. {
  65. int n=5;
  66. int m=3;
  67. int a[][2]={{1,2},{2,3},{4,5}};
  68. cout << friends(n,m,a) <<endl;
  69. }  
    1. http://blog.csdn.net/bxyill/article/details/8965530#comment

      1. 转载请注明:http://krystism.is-programmer.com/若有错误,请多多指正,谢谢!

        题目描述:假如已知有n个人和m对好友关系(存于数字r)。如果两个人是直接或间接的好友(好友的好友的好友...),则认为他们属于同一个朋友圈,请写程序求出这n个人里一共有多少个朋友圈。

        假如:n = 5 , m = 3 , r = {{1 , 2} , {2 , 3} , {4 , 5}},表示有5个人,1和2是好友,2和3是好友,4和5是好友,则1、2、3属于一个朋友圈,4、5属于另一个朋友圈,结果为2个朋友圈。 最后请分析所写代码的时间、空间复杂度。评分会参考代码的正确性和效率。

        显然本质就是求无向图的连通分量个数。而要求连通分量数,就是遍历图的过程。遍历完所有节点,需要调用遍历几次就是连通分量个数。比如题目中使用DFS,从节点1出发,可以遍历节点2,3,而要遍历完所有节点还需从节点4出发,再遍历一次,共遍历两次,因此连通分量数为2。实现代码如下:

        ?
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
        #define N 10000
        char map[N][N];
        char used[N];
        void dfs(int i, int n)
        {
            int j;
            used[i] = 1;
            for(j = 1; j <= n; j++) {
                if (map[i][j] && !used[j])
                    dfs(j, n);
            }
        }
        /* 判断是否存在未访问节点
         * 若存在,则返回第一个未访问节点编号
         * 若不存在,则返回-1
         */
        int isVisitedAll(int n)
        {
            int i;
            for (i = 1; i <= n; i++)
                if (used[i] == 0)
                    return i;
            return -1;
        }
        int main(int argc, char **argv)
        {
            int n, m;
            int a, b, i, sum, cur;
            while (scanf("%d%d", &n, &m) != EOF) {
                if (n == 0)
                    break;
                memset(map, 0, sizeof(map));
                memset(used, 0, sizeof(used));
                sum = 0;
                for (i = 0; i < m; i++) {
                    scanf("%d%d", &a, &b);
                    map[a][b] = map[b][a] = 1;
                }
                while((cur = isVisitedAll(n)) != -1) {
                    sum++;
                    dfs(cur, n);
                }
                printf("%d\n", sum);
            }
            return 0;
        }

        暂且不说时间复杂度吧,空间复杂度就足够吓人了。首先需要一个表示图的01矩阵,大小为O(n  * n), 还需要记录是否节点是否已经被访问,需要大小为O(n)的空间。

        换一种思路,其实根据题目朋友圈,我们就应该想到每一个圈其实就是一个集合,存在关系的,归为一个集合中,最后即需要求有多少个不相交的集合即有多少个圈子。由此不难想出,这其实就是并查集。不了解并查集可以查看维基百科并查集

        想到了并查集,不难写出代码:

        ?
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        26
        27
        28
        29
        30
        31
        32
        33
        34
        35
        36
        37
        38
        39
        40
        41
        42
        43
        44
        45
        46
        47
        48
        49
        50
        51
        52
        53
        54
        55
        56
        57
        58
        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
        #define N 100000
        int father[N];
        void init(int n)
        {
            int i;
            for (i = 1; i <= n; i++)
                father[i] = i;
        }
        int getFather(int v)
        {
            if (father[v] == v)
                return v;
            else {
                father[v] = getFather(father[v]);
                return father[v];
            }
        }
        void merge(int x, int y)
        {
            int fx = getFather(x);
            int fy = getFather(y);
            if (fx < fy)
                father[fx] = fy;
            else
                father[fy] = fx;
        }
        int same(int x, int y)
        {
            return getFather(x) == getFather(y);
        }
        int main(int argc, char **argv)
        {
            int n, m;
            int a, b;
            int i;
            int sum;
            while (scanf("%d%d", &n, &m) != EOF) {
                if (n == 0)
                    break;
                init(n);
                sum = 0;
                for (i = 1; i <= m; i++) {
                    scanf("%d%d", &a, &b);
                    merge(a, b);
                }
                for (i = 1; i <= n; i++) {
                    if (getFather(i) == i)
                        sum++;
                }
                printf("%d\n", sum);
            }
            return 0;
        }

        显然空间大大减少了,只需要O(n)的空间。

转载于:https://www.cnblogs.com/zhizhan/p/4868120.html

【互联网面试】朋友圈问题相关推荐

  1. 这些面试用例设计,你肯定遇到过(朋友圈、电梯、发红包、支付)

    1.朋友圈点赞以及评论测试用例 功能测试 1 是否可以点赞成功 2 点赞成功后是否可以去取消 3 没有网络情况下是否可以点赞 4 点赞成功后是否可以评论 5 是否按照点赞顺序,按时间进行排序 6 点赞 ...

  2. 面试结束后,被面试官在朋友圈吐槽了......

    前一阵子有个小学弟向我诉苦,说自己在参加某大厂测试面试的时候被面试官怼得哑口无言,场面让他一度十分尴尬 印象最深的就是下面几个问题: 根据你以前的工作经验和学习到的测试技术,说说你对质量保证的理解? ...

  3. 面试阿里测试开发,面试结束后,还被面试官在朋友圈吐槽“什么阿猫阿狗都敢来面试大厂了吗?”

    前一阵子有个小徒弟向我诉苦,说自己在参加某大厂测试面试的时候被面试官怼得哑口无言,场面让他一度十分尴尬 印象最深的就是下面几个问题: 根据你以前的工作经验和学习到的测试技术,说说你对质量保证的理解? ...

  4. 来前端君朋友圈,一起聊前端面试技巧

    查看全文 http://www.taodudu.cc/news/show-1159855.html 相关文章: 公司鼓励程序员不要加班,去约会! 连续加班2周做出来的功能,老板说先不做了 科普!程序员 ...

  5. 【朋友圈精选】web前端招聘面试的10个小分享

    web前端教程 用大白话,来讲编程 上一篇<敲得慢一点,学得快一点>也提到了,上个月给团队招纳贤才的时候,面试过程中总结了一些想法见和笑料,在微信朋友圈和大家分享了.希望给马上毕业找工作或 ...

  6. 有道少儿词典正式上线,CEO周枫发朋友圈:“是时候让小学生词典进入互联网时代了”...

    雷锋网消息,1月3日,有道少儿词典正式上线,据介绍,该款词典专为小学生的语文和英语学习设计,从内容.功能到交互体验实现全方位的少儿化,堪称有道词典"少儿版". 为什么推出有道词典& ...

  7. 朋友圈怎么设计测试用例,面试官听完都惊呆了

    (资深面试官,每天更新常问面试题,内含100个用例设计) 姐妹们,大家在面试前都花了很多时间精力收集题目.但我想温柔的提醒:粗制滥造的答案不仅对面试毫无帮助,反而会浪费宝贵的面试机会.很多姐妹就找着这 ...

  8. PC端抖音HTML布局,从抖音网页版上线、微信PC版可发朋友圈,看互联网「全端化」布局...

    三哥觉得,不管是用户价值,还是商业价值,都极大. 先说用户价值. 比如,当你在用电脑期间,想发或看朋友圈,之前只能打开手机进行操作,这很割裂,现在直接在电脑上完成了,很顺畅. 短视频.娱乐视频,适合手 ...

  9. 如何在朋友圈刷出宝马广告-互联网推荐系统

    近期发布了两篇推荐系统的文章: 从0开始做互联网推荐-以58转转为例(或回复[推荐]查看) 从0开始做垂直O2O个性化推荐-以58到家美甲为例(或回复[O2O]查看) 简单介绍了协同过滤推荐.分类预测 ...

最新文章

  1. 华为不造车,广汽合作智能驾驶
  2. FreeTextBox1.6版本控件使用总结(未完)
  3. htm怎么让图片和搜索框在同一行_新手怎么玩好小红书
  4. rabbitmq-java生产者消费者
  5. 在Windows上安装Elasticsearch 5.0
  6. 11-Docker Bridge详解
  7. 如何在android模拟器中安装apk
  8. java unit test怎么写_Java J Unit Test
  9. java servlet 对象_java servlet的域对象
  10. hadoop配置集群的心得
  11. 数据介绍与描述性分析——以NBA球员薪酬影响因素分析为例
  12. 蓝牙学习笔记之SMP协议(十四)
  13. 第二章补充____微分中值定理及导数应用
  14. appium测试代码nullpoint
  15. 2022 年的 React 生态
  16. Cocos 2.x 扩展开发教程
  17. MAC系统的绝佳看图工具iSmartPhoto
  18. 一、C++语法基础(浅谈)
  19. C语言入门之变量、常量、字符串、转义字符
  20. 阿里云网页跳转淘宝app授权登陆流程

热门文章

  1. BatchNormalization对cnn训练的影响
  2. Linux云服务器上python画图并保存
  3. mysql和oracle执行计划_mysql explain执行计划详解
  4. 服务器虚拟化北向,KVM虚拟化的部署及使用
  5. linux 节点信,DOM 节点信息
  6. php程序应用实例,PHP教程.应用实例1_php
  7. mysql游标示例mysql游标简易教程
  8. CentOS6静态网络配置
  9. 如何找到php的配置文件,如何查找PHP配置文件php.ini所在路径
  10. php实现项目的日志记录功能,tp5框架使用composer实现日志记录功能示例