想成为Google工程师?先回答这15个面试问题【这只是一必要条件】(三)

3.给出一组区间(以秒计),让你找出重叠的部分
挑战: Google一般也会要你解决一堆数学问题。

这些设计的意图是让工程师对问题进行有效的思考,而不是仅仅知道如何对每个问题进行编码。

此处的问题会要你实现一个聪明的数学技巧。

     题目讲的不是很好理解,看来写这博客的不是google的工程师吧。给出一组区间,不知道找的是所有区间的重叠部分,还是任意区间的重叠部分,其次输入的数据按秒计是指精确到秒,还是输入的数据就是秒,姑且按任意区间的重叠,然后输入数据就是秒(包含分钟的,可以转化为秒,感觉影响不是很大)吧。我大概有两种思路:

      第一种想法:是切割法,算出所有区间的时间范围,假设为(START,END),那么从START到END的每秒去切割区间,如果这一秒落到两个区间内部,那么这秒属于重叠区间(如果是所有区间的重叠部分,那么就是落在全部区间的内部),时间复杂度为(END-START)* n(n为区间个数),显然这种方法对于区间比较大的情况是不符合的。

      第二种想法:对区间(a,b)按照a进行排序,然后可以根据两两相邻区间进行比较,计算重叠区间。

     时间复杂度为排序时间O(nlogn)+遍历时间O(n),源代码如下:

//The program used to get the overlay period 
//input format
//M //the number of the period m (1, 100)
//a b //M line
#include <iostream>
#include <fstream>
#include <stdlib.h>

using namespace std;

#define min(a,b) ((a)>(b)?(b) :(a))
#define max(a,b) ((a)>(b)?(a):(b))

//the read file stream 
ifstream fin("input.txt");
ofstream fout("output.txt");

// the period of the time
struct Period
{
	int s;
	int e;
};

const int MSIZE = 100;
int m;
Period period[MSIZE];
Period overlay[MSIZE];
int ol = 0;

//read the period
void read()
{
	fin >> m;

	for (int i=0; i < m;i ++)
	{
		fin >>period[i].s >> period[i].e;
	}
}

//the compare used to qsort the array
int compare(const void * a, const void * b)
{
	return (((Period* )a)->s) - (((Period*)b)->s);
}

void overlayperiod()
{
	qsort(period, m, sizeof(Period), compare);
	
	Period  cur = period[0];

	for (int i=1; i < m; i ++)
	{
		//exist the overlay period
		if (cur.e > period[i].s && cur.s < period[i].e)
		{
			overlay[ol].s = max(cur.s, period[i].s);
			overlay[ol].e = min(cur.e, period[i].e);
			cur.s =  overlay[ol].e;
			cur.e = max(cur.e, period[i].e);
			ol ++;
		}
		else
		{
			//cur = period[i];
			cur.s = period[i].s;
			cur.e = period[i].e;
		}//end else
	}//end for
}

//print the result
void print()
{
	for (int i=0; i < ol; i ++)
	{
		fout << "("<< overlay[i].s << ", " << overlay[i].e << ");";
	}
}

int main()
{
	read();
	overlayperiod();
	print();
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值