题目一
思路
拿到题目,一定先读好题!!!!!总结一下:这就是到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;
}
};
所有代码均以通过力扣测试
(经过多次测试最短时间为):
题目二
思路:贪心法
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;
}
};
所有代码均以通过力扣测试
(经过多次测试最短时间为):
题目三
思路
暴力模拟
代码
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;
}
};
所有代码均以通过力扣测试
(经过多次测试最短时间为):