当前位置:   article > 正文

华为面试算法题_华为算法题

华为算法题

华为面试算法题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;
}
  • 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
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68

华为面试算法题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;
}
  • 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

华为面试算法题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;
}
  • 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
  • 59
  • 60
  • 61
  • 62

方法二递归

#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;
}

  • 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
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/229613
推荐阅读
相关标签
  

闽ICP备14008679号