5922.统计出现过一次的公共字符串
好久没做双周赛了,没想到这第一场就碰到这么水的题,让我给ak了,太离谱了。
题目描述
给你两个字符串数组
words1
和words2
,请你返回在两个字符串数组中 都恰好出现一次 的字符串的数目。
示例 1:
输入:words1 = ["leetcode","is","amazing","as","is"], words2 = ["amazing","leetcode","is"]
输出:2
解释:
- "leetcode" 在两个数组中都恰好出现一次,计入答案。
- "amazing" 在两个数组中都恰好出现一次,计入答案。
- "is" 在两个数组中都出现过,但在 words1 中出现了 2 次,不计入答案。
- "as" 在 words1 中出现了一次,但是在 words2 中没有出现过,不计入答案。
所以,有 2 个字符串在两个数组中都恰好出现了一次。
解题思路
建立两个哈希表记录出现的词频,之后遍历某一个哈希表,判断该字符串是否在两个哈希表中都只出现一次。
public int countWords(String[] words1, String[] words2) {
Map<String,Integer> wordMap1 = new HashMap<>();
Map<String,Integer> wordMap2 = new HashMap<>();
for(String s:words1){
wordMap1.put(s, wordMap1.getOrDefault(s, 0)+1);
}
for(String s:words2){
wordMap2.put(s, wordMap2.getOrDefault(s, 0)+1);
}
int ans = 0;
for(String s:wordMap1.keySet()) {
if(wordMap1.get(s)==1&&wordMap2.getOrDefault(s, 0)==1) {
ans++;
}
}
return ans;
}
5923. 从房屋收集雨水需要的最少水桶数
给你一个下标从 0 开始的字符串
street
。street
中每个字符要么是表示房屋的'H'
,要么是表示空位的'.'
。你可以在 空位 放置水桶,从相邻的房屋收集雨水。位置在
i - 1
或者i + 1
的水桶可以收集位置为 i 处房屋的雨水。一个水桶如果相邻两个位置都有房屋,那么它可以收集 两个 房屋的雨水。在确保每个房屋旁边都 至少 有一个水桶的前提下,请你返回需要的最少水桶数。如果无解请返回
-1
。
示例 1:
输入:street = "H..H"
输出:2
解释:
我们可以在下标为 1 和 2 处放水桶。
"H..H" -> "HBBH"('B' 表示放置水桶)。
下标为 0 处的房屋右边有水桶,下标为 3 处的房屋左边有水桶。
所以每个房屋旁边都至少有一个水桶收集雨水。
解题思路
我的思路就是贪心,如果当前是H判断右遍能不能放,能放就放,不能就放左边,左边也不能放就返回-1.
public int minimumBuckets(String street) {
int[] nums = new int[street.length()];
for(int i=0;i<street.length();i++) {
if(street.charAt(i)=='H') {
if(i>=1&&nums[i-1]==1) {
continue;
}
if(i==street.length()-1) {
if(i<1||street.charAt(i-1)=='H') {
return -1;
}
nums[i-1]=1;
}else {
if(street.charAt(i+1)=='H') {
if(i<1||street.charAt(i-1)=='H') {
return -1;
}
nums[i-1]=1;
}else {
nums[i+1]=1;
}
}
}
}
int ans=0;
for(int i=0;i<nums.length;i++) {
if(nums[i]==1) {
ans++;
}
}
return ans;
}
5924. 网格图中机器人回家的最小代价
给你一个
m x n
的网格图,其中(0, 0)
是最左上角的格子,(m - 1, n - 1)
是最右下角的格子。给你一个整数数组startPos ,startPos = [startrow, startcol]
表示初始有一个 机器人 在格子(startrow, startcol)
处。同时给你一个整数数组homePos ,homePos = [homerow, homecol]
表示机器人的 家 在格子(homerow, homecol)
处。机器人需要回家。每一步它可以往四个方向移动:上,下,左,右,同时机器人不能移出边界。每一步移动都有一定代价。再给你两个下标从 0 开始的额整数数组:长度为 m 的数组
rowCosts
和长度为n
的数组colCosts
。如果机器人往 上 或者往 下 移动到第 r 行 的格子,那么代价为 rowCosts[r] 。
如果机器人往 左 或者往 右 移动到第 c 列 的格子,那么代价为 colCosts[c] 。
请你返回机器人回家需要的最小总代价。
示例 1:
输入:startPos = [1, 0], homePos = [2, 3], rowCosts = [5, 4, 3], colCosts = [8, 2, 6, 7]
输出:18
解释:一个最优路径为:
从 (1, 0) 开始
-> 往下走到 (2, 0) 。代价为 rowCosts[2] = 3 。
-> 往右走到 (2, 1) 。代价为 colCosts[1] = 2 。
-> 往右走到 (2, 2) 。代价为 colCosts[2] = 6 。
-> 往右走到 (2, 3) 。代价为 colCosts[3] = 7 。
总代价为 3 + 2 + 6 + 7 = 18
解题思路
这题就离谱,一开始只想着用bfs做,后来发现,这特么不就只能走最短路径吗。。。
不知道这题想考察什么。
public static int minCost(int[] startPos, int[] homePos, int[] rowCosts, int[] colCosts) {
int ans = 0;
if(startPos[0]<homePos[0]) {
for(int i=startPos[0]+1;i<=homePos[0];i++) {
ans+=rowCosts[i];
}
}
if(startPos[0]>homePos[0]) {
for(int i=homePos[0];i<startPos[0];i++) {
ans+=rowCosts[i];
}
}
if(startPos[1]<homePos[1]) {
for(int i=startPos[1]+1;i<=homePos[1];i++) {
ans+=colCosts[i];
}
}
if(startPos[1]>homePos[1]) {
for(int i=homePos[1];i<startPos[1];i++) {
ans+=colCosts[i];
}
}
return ans;
}
5925. 统计农场中肥沃金字塔的数目
题目描述
有一个 矩形网格 状的农场,划分为 m 行 n 列的单元格。每个格子要么是 肥沃的 (用 1 表示),要么是 贫瘠 的(用 0 表示)。网格图以外的所有与格子都视为贫瘠的。
农场中的 金字塔 区域定义如下:
区域内格子数目 大于 1 且所有格子都是 肥沃的 。
金字塔 顶端 是这个金字塔 最上方 的格子。金字塔的高度是它所覆盖的行数。令 (r, c) 为金字塔的顶端且高度为 h ,那么金字塔区域内包含的任一格子 (i, j) 需满足 r <= i <= r + h - 1 且 c - (i - r) <= j <= c + (i - r) 。
一个 倒金字塔 类似定义如下:区域内格子数目 大于 1 且所有格子都是 肥沃的 。
倒金字塔的 顶端 是这个倒金字塔 最下方 的格子。倒金字塔的高度是它所覆盖的行数。令 (r, c) 为金字塔的顶端且高度为 h ,那么金字塔区域内包含的任一格子 (i, j) 需满足 r - h + 1 <= i <= r 且 c - (r - i) <= j <= c + (r - i) 。
下图展示了部分符合定义和不符合定义的金字塔区域。黑色区域表示肥沃的格子。
给你一个下标从 0 开始且大小为 m x n 的二进制矩阵 grid ,它表示农场,请你返回 grid 中金字塔和倒金字塔的 总数目 。
示例1:
输入:grid = [[0,1,1,0],[1,1,1,1]]
输出:2
解释:
2 个可能的金字塔区域分别如上图蓝色和红色区域所示。
这个网格图中没有倒金字塔区域。
所以金字塔区域总数为 2 + 0 = 2 。
解题思路
这题也离谱,居然直接暴力能过,对每个点判断是否能成金字塔,能的话加上半径。
public int countPyramids(int[][] grid) {
int ans = 0;
int[][] grid2 = new int[grid.length][grid[0].length];
for(int i=0;i<grid.length;i++) {
grid2[i] = grid[grid.length-i-1];
}
for(int i=0;i<grid.length;i++) {
for(int j=0;j<grid[i].length;j++) {
if(grid[i][j]==1) {
int r = 0;
if((r=isOk(grid,i,j))>0) {
ans+=r;
}
if((r=isOk(grid2,i,j))>0) {
ans+=r;
}
}
}
}
return ans;
}
private int isOk(int[][] grid, int x, int y) {
int r = 1;
while(true) {
if(isOok(x,y,r,grid)) {
r++;
}else {
return r-1;
}
}
}
private boolean isOok(int x, int y, int r, int[][] grid) {
int row = x+r;
if(row>=grid.length||y-r<0||y+r>=grid[row].length) {
return false;
}
for(int i=y-r;i<=y+r;i++) {
if(grid[row][i]!=1) {
return false;
}
}
return true;
}
这场周赛做完,一点成就感都没有。。。
也记录下吧,毕竟是一次ak。