查看: 2830| 回复: 5
跳转到指定楼层
上一主题 下一主题
收起左侧

Google : Find intersected circles

全局:

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
Given an array A of N integers we draw N discs in a 2D plane, such that i-th disc has
center in (0,i) and a radius A[i]. We say that k-th disc and j-th disc intersect,
if $k\not =j$ and k-th and j-th discs have at least one common point.
Write a function
class Solution { public int number_of_disc_intersections(int[] A); }
which given an array A describing N discs as explained above, returns the number of
pairs of intersecting discs. For example, given N=6 and
\begin{displaymath}A[0]=1 A[1]=5 A[2]=2 A[3]=1 A[4]=4 A[5]=0\end{displaymath}
there are 11 pairs of intersecting discs:
0th and 1st
0th and 2nd
0th and 4th
1st and 2nd
1st and 3rd
1st and 4th
1st and 5th
2nd and 3rd
2nd and 4th
3rd and 4th
4th and 5th
so the function should return 11.
The function should return -1 if the number of intersecting pairs exceeds 10,000,000.
The function may assume that N does not exceed 10,000,000.

上一篇:Google : Eliminate duplicated bit arrays
下一篇:Google : Link addition
🔗
 楼主| wwwyhx 2011-7-27 15:02:53 | 只看该作者
全局:
实际上这道题就是求线段重叠的问题, 不过这里有一个很方便的计算线段重叠的方法:
1 把所有线段的两个端点拆开,合并并排序, 注意要记录端点是启始点还是终结点
2 从小到大遍历这些端点,通过下面这个算法计算重叠:
int nCount = 0;
        int nRet = 0;
        for (vector<END>::iterator it = vec.begin();
                it != vec.end(); it++)
        {
                if (it->bLft) // start point
                        nCount++;
                else // end point
                {
                        nCount--;
                        nRet += nCount;
                }
        }

  1. struct END
  2. {
  3.         int nVal;
  4.         bool bLft;
  5. };

  6. bool LessThan(const END& a, const END& b)
  7. {
  8.         return a.nVal < b.nVal;
  9. }

  10. int GetIntersections(int A[], int n)
  11. {
  12.         assert(A && n > 0);

  13.         vector<END> vec;
  14.         for (int i = 0; i < n; i++)
  15.         {
  16.                 END ed1, ed2;

  17.                 ed1.nVal = i - A[i];
  18.                 ed1.bLft = true;
  19.                 ed2.nVal = i + A[i];
  20.                 ed2.bLft = false;

  21.                 vec.push_back(ed1);
  22.                 vec.push_back(ed2);
  23.         }

  24.         sort(vec.begin(), vec.end(), LessThan);

  25.         int nCount = 0;
  26.         int nRet = 0;
  27.         for (vector<END>::iterator it = vec.begin();
  28.                 it != vec.end(); it++)
  29.         {
  30.                 if (it->bLft) // start point
  31.                         nCount++;
  32.                 else // end point
  33.                 {
  34.                         nCount--;
  35.                         nRet += nCount;
  36.                 }
  37.         }

  38.         return nRet;
  39. }
复制代码
回复

使用道具 举报

🔗
darksteel 2011-7-29 12:37:03 | 只看该作者
全局:
回复 2# wwwyhx
这方法还挺巧的,排完虚之后O(n)就可以了。之前见过类似的题目我能想到的就是先把线段按起始位置排序,然后对于每个线段segment[ i ],在它后面的线段中找到第一个起始位置大于segment[ i ].end的线段,把中间的线段全count进去。查找可以二分,总的复杂度也是O(nlogn)。
回复

使用道具 举报

🔗
Alice0701 2016-3-21 06:19:40 | 只看该作者
全局:
LZ的方法好机智!!!太聪明了
回复

使用道具 举报

🔗
ccarter 2016-3-23 04:51:42 | 只看该作者
全局:
这坟挖的……
这个想法不错,但是代码错了吧?在比较函数那里,如果两个点的nVal相等,应该是bLft==true的排在前面
回复

使用道具 举报

🔗
Alice0701 2016-3-23 04:58:40 | 只看该作者
全局:
ccarter 发表于 2016-3-23 04:51
这坟挖的……
这个想法不错,但是代码错了吧?在比较函数那里,如果两个点的nVal相等,应该是bLft==true的 ...

对哈!! 多亏你指出来,我都忽视这点了!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表