力扣第 66 场双周赛

本文介绍了力扣第66场双周赛的三道题目,分别是机器人回家的最小代价问题、雨水收集的最少水桶数问题和统计公共字符串的个数。解题思路包括直接计算、贪心算法和暴力模拟,通过代码实现展示了如何解决这些编程挑战。
摘要由CSDN通过智能技术生成

第一百零七天 --- 力扣第 66 场双周赛

题目一

力扣:2087. 网格图中机器人回家的最小代价

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

思路

拿到题目,一定先读好题!!!!!总结一下:这就是到TM的脑筋急转弯。。。。
1、乍一看,和我们平时的机器人走路问题,很相似,一定要仔细读题呀!
2、他的代价计算规则是,走到第i行,花费rowCosts[i],一次只能走一步。那么我从当前行列直接不绕路的走到目的地,经过的行列,就是固定的
3、如果我们不那样直达,而采取非直达,上述花费一定少不了,并且还得多出到无用行列的费用
4、综上,直达费用最小。

代码

class Solution {
public:
	int minCost(vector<int>& startPos, vector<int>& homePos, vector<int>& rowCosts, vector<int>& colCosts) {
		if (startPos[0] == homePos[0] && startPos[1] == homePos[1]) {
			return 0;
		}

		int sx = startPos[0], sy = startPos[1];//起始行列
		int hx = homePos[0], hy = homePos[1];//终止行列
		int ans = 0;
		
		//行
		if (sx <= hx) {//判断是小到大还是大到小
			for (int i = sx + 1; i <= hx; i++) {
				ans += rowCosts[i];
			}
		}
		else {
			for (int i = sx - 1; i >= hx; i--) {
				ans += rowCosts[i];
			}
		}

		//列
		if (sy <= hy) {//判断是小到大还是大到小
			for (int i = sy + 1; i <= hy; i++) {
				ans += colCosts[i];
			}
		}
		else {
			for (int i = sy - 1; i >= hy; i--) {
				ans += colCosts[i];
			}
		}
		return ans;
	}
}; 

所有代码均以通过力扣测试
(经过多次测试最短时间为):
在这里插入图片描述

题目二

力扣:2086. 从房屋收集雨水需要的最少水桶数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

思路:贪心法

1、我们要把桶放在空地上接房檐的水,并且还要桶最少,所以只有房子边上的空地有意义,如果一个房子两边都没有空地,则无解
2、同时也并不是所有房子边上的空地都要,记住我们的目的,让桶最少,所以一个桶要尽可能的发挥最大的用处
3、所以每审视一个空地他的价值的时候,如果他的两边都有房子,并且这两个房子旁边都没有水桶接,为2,反之为1,为0代表放不了。
4、最后,每一次放水桶都优先放在价值大的一侧。
5、至此,便分析完毕了。

代码

class Solution {
public:
	int minimumBuckets(string street) {
		unordered_set<int> item;//所有空地位置,放完水桶后消失
		unordered_set<int> item_H;//也是所有房子位置,用于快速匹配
		unordered_set<int> right;//已经有水桶的房屋
		vector<int> H;//存所有房子位置
		int ans = 0;

		for (int i = 0; i < street.size(); i++) {//初始化
			if (street[i] == 'H') {
				H.push_back(i);
				item_H.insert(i);
			}
			else {
				item.insert(i);
			}
		}

		for (int i = 0; i < H.size(); i++) {
			if (right.count(H[i]) == 0) {//已经有水桶的房子跳过
				ans++;
				int pos_l = H[i] - 1;//左右放水桶位置
				int pos_r = H[i] + 1;
				int cnt_l = 0;//价值
				int cnt_r = 0;
				if (item.count(pos_l) > 0) {//能放水桶
					if (item_H.count(pos_l - 1) > 0 && right.count(pos_l - 1) == 0) {//该水桶左右两侧都有未有水桶的屋子
						cnt_l = 2;
					}
					else {
						cnt_l = 1;
					}
				}
				if (item.count(pos_r) > 0) {//右侧同理
					if (item_H.count(pos_r + 1) > 0 && right.count(pos_l + 1) == 0) {
						cnt_r = 2;
					}
					else {
						cnt_r = 1;
					}
				}
				if (cnt_l == 0 && cnt_r == 0) {//两边都放不了。无解
					return -1;
				}
				else if (cnt_l > cnt_r) {//挑价值大的一边
					item.erase(pos_l);//擦除位置
					if (cnt_l == 2) {
						right.insert(H[i]);
						right.insert(H[i] - 2);
					}
					else {
						right.insert(H[i]);
					}
				}
				else {
					item.erase(pos_r);
					if (cnt_r == 2) {
						right.insert(H[i]);
						right.insert(H[i] + 2);
					}
					else {
						right.insert(H[i]);
					}
				}
			}


		}
		return ans;
	}
};

所有代码均以通过力扣测试
(经过多次测试最短时间为):
在这里插入图片描述

题目三

力扣:2085. 统计出现过一次的公共字符串

在这里插入图片描述
在这里插入图片描述

思路

暴力模拟

代码

class Solution {
public:
	int countWords(vector<string>& words1, vector<string>& words2) {
		unordered_map<string, int> item1;
		unordered_map<string, int> item2;
		int ans = 0;
		for (string tmp : words1) {
			item1[tmp]++;
		}
		for (string tmp : words2) {
			item2[tmp]++;
		}
		for (int i = 0; i < words1.size(); i++) {
			if (item1[words1[i]] == 1) {
				if (item2[words1[i]] == 1) {
					ans++;
				}
			}
		}
		return ans;
	}
};

所有代码均以通过力扣测试
(经过多次测试最短时间为):
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JLU_LYM

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值