华为面试算法题

华为面试算法题1

给定一个n*2的二维数组,表示有n个任务,一个信息是任务能够开始做的时间,,另一个信息是任务的结束期限。后者一定大于前者,且数值上都是正数,你作为单线程的人,不能并行处理任务,
但是每个任务都只需要一个单位时间完成
你需耍将所有任务的执行时间,位于开始做的时间和最后期限之间,返回你能否做到这—点。

最重要的是判断任务优先级
如何进行最优调度:

  • 开始时间和结束时间放在一个数组里面进行排序,同时,开始时间带上自己的结束时间,结束时间带上自己的开始时间。
  • 开始时间是用来收集任务,结束时间是为了验证这个结束时间的任务有没有做完。同样的开始时间先做最先结束的任务。
  • 遍历数组。一旦存在时间差。
  • 开始时间相同就将其加入到小根堆中,此时小根堆根据这些开始时间的结束时间排序,最紧迫的任务最先做。
  • 当遇到了一个结束时间,小根堆中还存在比结束时间小的结束时间,那么就不能完成所有任务。
#include <string>
#include <sstream>
#include <iostream>
#include <vector>
#include<algorithm>
#include<queue>
using namespace std;

struct TimePoint {

	int time;//时间,开始时间或者结束时间
	int end;
	bool add;	//if add== true,任务开始时间,else 任务结束时间。
	TimePoint(int t, int e, int a) {
		time = t;
		end = e;
		add = a;
	}
};

bool canDo(vector<vector<int>>jobs)
{
	if (jobs.size() == 0 || jobs.size() == 1)
	{
		return true;
	}
	int n = jobs.size();
	vector<TimePoint>arr(n * 2);
	//一个任务分成两个事件。
	for (int i = 0; i < n; i++)
	{
		arr[i] = (TimePoint(jobs[i][0], jobs[i][1], true));
		arr[i + n] = (TimePoint(jobs[i][1], jobs[i][0], false));
	}

	sort(arr.begin(), arr.end(), [](TimePoint & a, TimePoint & b)
		{
			return a.time < b.time;
		});
	//准备一个小根堆
	priority_queue<int>heap;
	//lastTime为上一个时间,判断是否有时间差。
	for (int i = 0, lastTime = arr[0].time; i < arr.size(); i++)
	{
		//如果是一个添加的事件。
		if (arr[i].add)
		{
			heap.push(arr[i].end);
		}
		else {	//闭
			int curTime = arr[i].time;	//当前时间
			for (int j = lastTime; i < curTime; j++)
			{
				if (heap.empty())
				{
					break;
				}
				heap.pop();
			}//能做几个任务

			if (heap.top() <= curTime)
			{
				return false;
			}
		}
	}
	return true;
}

华为面试算法题2-???

给定一个数组arr,可能有正、有负、有0,无序
只能挑选两个数字,想尽量让两个数字加起来的绝对值尽量小返回可能的最小的值
这两个的选择:
1.两个都是正数的情况
2.两个都是负数的情况
3.一个正数一个负数的情况
????

#include <string>
#include <sstream>
#include <iostream>
#include <vector>
#include<algorithm>
#include<queue>
using namespace std;

int main()
{
	int n; 
	cin >> n;

	vector<int>arr(n, 0);
	for (int i = 0; i < n; i++)
	{
		cin >> arr[i];
	}
	sort(arr.begin(), arr.end());
	
	//排序+双指针
	int res = INT_MAX;
	int l = 0, r = n - 1;
	int sum = 0;
	while (l <= r)
	{
		sum = arr[l] + arr[r];
		res = min(res, sum);
		if (sum > 0)
		{
			r--;
		}
		else {
			l++;
		}
	}
	cout << res << endl;
}

华为面试算法题3-绝处逢生

小草被迫加入了一个无法退出的游戏最终只能活下一人,100个人站成一圈,各自标上1-100的号码。每人身上持有一把电枪,游戏从1号开始每人必须用电枪击中顺时针的下一个顺位,存活的人必须顺时针向下一个依然存活的开枪,请问小草应该站在哪个位置才能活下来?

1.第一次:1号击杀2号,3号击杀4号。。。。所有的偶数位都被击杀。存活50人
2.第二次:主动权依然在1号手中,1号击杀3号,5号击杀7号,9号击杀11号,存活25人。

每次人数减半,当人数为2的n次方时,最后会变成2个人,那么1号杀死2号,存活为1号。

假设现在人数为40人,最接近的为32人,首先杀死八个人,此时将17号设置为1号,然后每次循环减半,那么最后存活下来的人为17号。

在这里插入图片描述
100人时,
2的6次方为64人,首先淘汰36个人。
第一轮淘汰,2,4,6,8,10…2*36,即淘汰36个人之后的第一个人为73。
最终存活的人为73

华为面试算法题4(默认升序。。)

方法一存疑

给定两个数组A和B,长度都是N
A[i]不可以在A中和其他数交换,只可以选择和B[i]交换(0<=i<n)你的目的是让A有序,返回你能不能做到。
0-i-1个交换有序,尽可能让A中的值小,然后判断i位置是否交换后能能判断有序

#include <string>
#include <sstream>
#include <iostream>
#include <vector>
#include<algorithm>
#include<queue>
using namespace std;

int main()
{
	int n;
	cin >> n;
	vector<int>arra(n);
	vector<int>arrb(n);
	for (int i = 0; i < n; i++)
	{
		cin >> arra[i];
	}
	for (int i = 0; i < n; i++)
	{
		cin >> arrb[i];
	}
	if (n <= 1)cout << true << endl;

	vector<bool>dp(n+1,false);
	dp[0] = true;
	for (int i = 1; i < n; i++)
	{
		if (i==1)
		{
			if (arra[i - 1] > arrb[i - 1])
			{
				swap(arra[i - 1], arrb[i - 1]);
				dp[i] = true;
			}
		}
		else {
			if (arra[i - 2] < arra[i - 1])
			{
				if (arra[i - 1] < arrb[i - 1])
				{
					dp[i] = dp[i - 1];
				}
				else if (arra[i - 2] < arrb[i - 1])
				{
					swap(arra[i - 1], arrb[i - 1]);
					dp[i] = dp[i - 1];
				}
			}
			else if (arra[i - 2] < arrb[i - 1])
			{
				swap(arra[i - 1], arrb[i - 1]);
				dp[i] = dp[i - 1];
			}
			else {
				dp[i] = false;
				break;
			}
		}
	}
	cout << dp[n] << endl;
}

方法二递归

#include <string>
#include <sstream>
#include <iostream>
#include <vector>
#include<algorithm>
#include<queue>
using namespace std;

bool canSorted(vector<int>&A, vector<int>&B)
{
	return process(A, B, 0, INT_MIN);
}
//已经扫过的部分:A[0...index - 1]已经过去了,在扫过的过程中,A[0...index - 1]能保证有序
//A[index....最后]能否也保证有序!

//1)不交换:A[index] ...
//2)交换:A[index]和 B[index]交换....pre A[index]

//返回能不能让A整体变有序!

bool process(vector<int>& A, vector<int>& B, int index, int pre)
{
	if (index == A.size())
	{
		return true;
	}
	//1.index不交换,A[index]
	bool p1 = pre > A[index] ? false : (process(A, B, index + 1, A[index]));

	//2.交换
	bool p2 = pre > B[index] ? false : (process(A, B, index + 1, B[index]));

	return p1 | p2;
}

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
专业面试我的技巧和经验: 一、 巧妇难为无米之炊,事前做一些功课是必须的,把自己学习过的和应聘岗位相关的内容复习下,比如性能与算法岗位:本科电子信息工程和通信工程这些课程肯定学过,通信原理,信息论和编码,信号与系统,数字信号处理,复习一下掌握大概的轮廓一个星期应该差不多可以搞定. 二、 善于引导面试官,比如当面试官问到什么问不懂的时候,避免连问几个都不懂,可以尝试这么说:我***方面的知识比较匮乏,不是很了解,但是我对***的知识还是比较熟习,我觉得***的知识在我们华为性能与算法工程师必须要掌握的吧。以我面试为例,面试问我3G和4G的关键技术,已经这些关键技术的基本原理,我是做雷达信号处理的,确实不懂。我就和面试官说:对不起,因为研究生期间主要做的雷达信号处理的工作,我对移动通信的知识了解甚少,但是我对移动通信的基础只是比如通信原理和调制解调技术还有一定的了解(当然这都是我事先复习好的),我觉得无论什么类型的通信技术都离不开这些基本的理论。接着面试官就让我说信源编码和信道编码的作用已经他们通常采用的方法,当然我也就能对答如流了。所以,引导很重要。 三、 专业面试对自己简历上不要为了蒙骗面试官,写的项目自己捡不熟悉,对简历上的东西一问三不知,语言表达不清楚,说不半天不能告诉面试官你做的工作内容和意义,这个很不好。 群面 一般10-14个人,看当天应聘的人数而定,分2组,一个话,让排序之类的,或者辩论之类的,不同的组会抽到不同的问,不同的地方也会有不同的问,在这里把问说出来没什么意义,这一轮会有很多意想不到的情况,比如这组我本来不是选为组长,但是在做总结的时候面试官让我做总结,或者突然问你刚才某某同学说的话你同意吗,或者突然说你今天脸色好像不好看之类的,所以灵机应变才是王道。群面一般要自我介绍,自我介绍要简短,不要说太多,我建议按以下几个方面说,自己学校专业、来自哪里、然后说自己学习,主要稍微说下自己的项目,说下名字就OK了,然后说自己做项目获得成果,比如发表文章,专利和之类的。然后说自己优点和缺点,一般情况下优点缺点都要说,而且我觉得最好优点缺点自己多准备几个,免得到时候你要说的前面的人都说了,就像我们这组:我开始说缺点的时候说我性格比较急,做什么事情都想快点做完,午觉也不睡,但是经常适得其反,中午不谁觉,下午就工作效率低。后面好几个同学说的时候都这么说了,惹的面试官说,你们重复一个东西说。说缺点的时候大家要慎重,不要说和自己工作相关的缺点,比如我们那个组一个同学说:我的缺点就是比较随性,重要场合经常穿拖鞋为此挨了不少批评。 面试官:。。。。(前面省略了一些),你这种随行的行为有同学提醒过你吗?

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值