第9场双周赛

1、最多可以买到的苹果数量

楼下水果店正在促销,你打算买些苹果,arr[i] 表示第 i 个苹果的单位重量。
你有一个购物袋,最多可以装 5000 单位重量的东西,算一算,最多可以往购物袋里装入多少苹果。

示例 1:
输入:arr = [100,200,150,1000]
输出:4
解释:所有 4 个苹果都可以装进去,因为它们的重量之和为 1450。

示例 2:
输入:arr = [900,950,800,1000,700,800]
输出:5
解释:6 个苹果的总重量超过了 5000,所以我们只能从中任选 5 个。

提示:
1 <= arr.length <= 10^3
1 <= arr[i] <= 10^3

public int maxNumberOfApples(int[] arr) {
	Arrays.sort(arr);
	int all = 0;
	for (int i = 0; i < arr.length; i++) {
		all += arr[i];
		if (all > 5000) {
			return i;
		}
	}
	return arr.length;
}

2、进击的骑士

一个坐标可以从 -infinity 延伸到 +infinity 的 无限大的 棋盘上,你的 骑士 驻扎在坐标为 [0, 0] 的方格里。
骑士的走法和中国象棋中的马相似,走 “日” 字:即先向左(或右)走 1 格,再向上(或下)走 2 格;或先向左(或右)走 2 格,再向上(或下)走 1 格。
每次移动,他都可以按图示八个方向之一前进。
现在,骑士需要前去征服坐标为 [x, y] 的部落,请你为他规划路线。
最后返回所需的最小移动次数即可。本题确保答案是一定存在的。

示例 1:

输入:x = 2, y = 1
输出:1
解释:[0, 0] → [2, 1]
示例 2:

输入:x = 5, y = 5
输出:4
解释:[0, 0] → [2, 1] → [4, 2] → [3, 4] → [5, 5]

提示:
|x| + |y| <= 300

public int minKnightMoves(int x, int y) {
	Set<Integer> oldSet = new HashSet<Integer>();
	Set<Integer> nowSet = new HashSet<Integer>();
	nowSet.add(getAns(0, 0));
	oldSet.add(getAns(0, 0));
	int value = 0;
	while (true) {
		Set<Integer> newSet = new HashSet<Integer>();
		for (Integer key : nowSet) {
			int xx = key / 2000 - 1000;
			int yy = key % 2000 - 1000;
			if (xx == x && yy == y) {
				return value;
			}
			int key1 = getAns(xx + 1, yy + 2);
			if (!oldSet.contains(key1)) {
				newSet.add(key1);
				oldSet.add(key1);
			}
			int key2 = getAns(xx + 1, yy - 2);
			if (!oldSet.contains(key2)) {
				newSet.add(key2);
				oldSet.add(key2);
			}
			int key3 = getAns(xx - 1, yy + 2);
			if (!oldSet.contains(key3)) {
				newSet.add(key3);
				oldSet.add(key3);
			}
			int key4 = getAns(xx - 1, yy - 2);
			if (!oldSet.contains(key4)) {
				newSet.add(key4);
				oldSet.add(key4);
			}
			int key5 = getAns(xx + 2, yy + 1);
			if (!oldSet.contains(key5)) {
				newSet.add(key5);
				oldSet.add(key5);
			}
			int key6 = getAns(xx + 2, yy - 1);
			if (!oldSet.contains(key6)) {
				newSet.add(key6);
				oldSet.add(key6);
			}
			int key7 = getAns(xx - 2, yy + 1);
			if (!oldSet.contains(key7)) {
				newSet.add(key7);
				oldSet.add(key7);
			}
			int key8 = getAns(xx - 2, yy - 1);
			if (!oldSet.contains(key8)) {
				newSet.add(key8);
				oldSet.add(key8);
			}
		}
		nowSet = newSet;
		value++;
	}
}

private int getAns(int x, int y) {
	return (x + 1000) * 2000 + y + 1000;
}

3、找出所有行中最小公共元素

给你一个矩阵 mat,其中每一行的元素都已经按 递增 顺序排好了。请你帮忙找出在所有这些行中 最小的公共元素。
如果矩阵中没有这样的公共元素,就请返回 -1。

示例:
输入:mat = [[1,2,3,4,5],[2,4,5,8,10],[3,5,7,9,11],[1,3,5,7,9]]
输出:5

提示:
1 <= mat.length, mat[i].length <= 500
1 <= mat[i][j] <= 10^4
mat[i] 已按递增顺序排列。

这道题有个重要的提示:1 <= mat[i][j] <= 10^4
我们可以把每个数字出现的次数都统计出来,第一个统计次数和数组长度一致的,就是最小公共元素

public int smallestCommonElement(int[][] mat) {
	int[] ans = new int[10001];
	for (int i = 0; i < mat.length; i++) {
		for (int j = 0; j < mat[i].length; j++) {
			ans[mat[i][j]]++;
		}
	}
	for (int i = 1; i < ans.length; i++) {
		if (ans[i] == mat.length) {
			return i;
		}
	}
	return -1;
}

4、建造街区的最短时间

你是个城市规划工作者,手里负责管辖一系列的街区。在这个街区列表中 blocks[i] = t 意味着第 i 个街区需要 t 个单位的时间来建造。
由于一个街区只能由一个工人来完成建造。
所以,一个工人要么需要再召唤一个工人(工人数增加 1);要么建造完一个街区后回家。这两个决定都需要花费一定的时间。
一个工人再召唤一个工人所花费的时间由整数 split 给出。
注意:如果两个工人同时召唤别的工人,那么他们的行为是并行的,所以时间花费仍然是 split。
最开始的时候只有 一个 工人,请你最后输出建造完所有街区所需要的最少时间。

示例 1:
输入:blocks = [1], split = 1
输出:1
解释:我们使用 1 个工人在 1 个时间单位内来建完 1 个街区。
示例 2:
输入:blocks = [1,2], split = 5
输出:7
解释:我们用 5 个时间单位将这个工人分裂为 2 个工人,然后指派每个工人分别去建造街区,从而时间花费为 5 + max(1, 2) = 7
示例 3:
输入:blocks = [1,2,3], split = 1
输出:4
解释:
将 1 个工人分裂为 2 个工人,然后指派第一个工人去建造最后一个街区,并将第二个工人分裂为 2 个工人。
然后,用这两个未分派的工人分别去建造前两个街区。
时间花费为 1 + max(3, 1 + max(1, 2)) = 4

提示:
1 <= blocks.length <= 1000
1 <= blocks[i] <= 10^5
1 <= split <= 100

这道题,我先开始的想法一直超时,所以比赛时候未能答题成功,后来看了别人代码,明白意思了
花费时间最小的两个工作,相当于一个花费时间+召唤时间的工作
利用了一个类PriorityQueue,该类属于队列,但是每次取值都是最小的值

public int minBuildTime(int[] blocks, int split) {
	PriorityQueue<Integer> priorityQueue = new PriorityQueue<Integer>();
	for (int i = 0; i < blocks.length; i++) {
		priorityQueue.add(blocks[i]);
	}
	while (priorityQueue.size() > 1) {
		int a = priorityQueue.poll();
		int b = priorityQueue.poll();
		priorityQueue.add(split + Math.max(a, b));
	}
	return priorityQueue.poll();
}
发布了127 篇原创文章 · 获赞 16 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_33321609/article/details/101203339