[网易互娱面试题]电梯调度算法

题目: 第i层有floors[i]位住户, 他们一起坐电梯, 只能在一层停下, 请问在哪层停下所有住户爬楼梯数目和最少?

约束:

第0层没有住户

首先是笨笨的暴力扫描法, 假设电梯在第i层, 则所有人要爬的层数为 ∑ k = 0 n ∣ k − i ∣ ∗ f l o o r s [ k ] \sum_{k=0}^n |k-i|*floors[k] k=0nkifloors[k]

外层循环为i[0,n]遍历, 内层循环为k[0,n]遍历, 时间复杂度 O ( N 2 ) O(N^2) O(N2), N为楼层数.

#define abs(x,y) x>y?x-y:y-x
int violentTraversal(vector<int> floors)
{
	int n = floors.size();
	int shortesti = 0;
	int shortestSteps = INT_MAX;
	for (int i = 1; i < n; i++)
	{
		int steps = 0;
		for (int k = 0; k < n; k++)
		{
			steps += floors[k] * abs(k,i);
		}
		if (steps<shortestSteps)
		{
			shortestSteps = steps;
			shortesti = i;
		}
	}
	return shortesti;
}

优化:

贪心法: 从第1层开始, 只要再往上一层需要麻烦楼下的人数<往上一层方便的楼下的人数, 则选择此层, 因为越往上, 上层的人越少, 能方便的人越少, 已经不可能再方便更多的人了!

从第1层开始, 楼层向上递增, 直到满足以上条件则退出, 最坏情况为搜索空间穷尽, 即位于最高层时, 退出循环. 时间复杂度 O ( N ) O(N) O(N), N为楼层数.

image-20200529214704441

int NFloorElevator(vector<int> floors)//第i层住户人数floors[i],认为第0层不住人
{
	//初始化,位于第1层时
	int i = 1;
	int n = floors.size();
	int N_1_i = floors[1];//第[0,i]层
	//位于第[2,n]层人数和
	int N_i_1_n = 0;
	for (int i = 2; i < n; i++)
	{
		N_i_1_n += floors[i];
	}

	for (; i < n; i++)
	{
		if (i==n-1//已经到达最高层,不能再往上了!
            || N_i_1_n < N_1_i) //往上一层方便楼上的人数<往上一层麻烦的楼下的以及当前层的人数
            break;
        N_1_i += floors[i+1];
        N_i_1_n -= floors[i+1];
	}
	return i;
}

简单测试:

void test(vector<int> v)
{
	if (violentTraversal(v) == NFloorElevator(v))
	{
		cout << "正确" << endl;
	}
	else
	{
		cout << "错误" << endl;
	}
}
int main()
{	
	test({ 0,2,3,4 });
	test({ 0,5,8,3,5 });
}

效果:

image-20200529215605987

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值