leetcode253场双周赛---好久没做了,第一场就碰到这么水的题。。。

博主分享了在LeetCode双周赛中的四道题目,包括统计出现过一次的公共字符串、收集雨水所需最少水桶数、机器人回家的最小代价以及农场中肥沃金字塔的数目。通过哈希表、贪心策略和二维矩阵遍历等方法解决题目,并对题目难度和解题体验进行了个人评价。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

5922.统计出现过一次的公共字符串

在这里插入图片描述
好久没做双周赛了,没想到这第一场就碰到这么水的题,让我给ak了,太离谱了。

题目描述

给你两个字符串数组words1words2,请你返回在两个字符串数组中 都恰好出现一次 的字符串的数目。

示例 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 开始的字符串streetstreet中每个字符要么是表示房屋的'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。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值