文章目录
- 周赛381
- [3014. 输入单词需要的最少按键次数 I](https://leetcode.cn/problems/minimum-number-of-pushes-to-type-word-i/)
- [3015. 按距离统计房屋对数目 I](https://leetcode.cn/problems/count-the-number-of-houses-at-a-certain-distance-i/)
- [3016. 输入单词需要的最少按键次数 II](https://leetcode.cn/problems/minimum-number-of-pushes-to-type-word-ii/)
- [3017. 按距离统计房屋对数目 II](https://leetcode.cn/problems/count-the-number-of-houses-at-a-certain-distance-ii/)
周赛381
3014. 输入单词需要的最少按键次数 I
简单
给你一个字符串 word
,由 不同 小写英文字母组成。
电话键盘上的按键与 不同 小写英文字母集合相映射,可以通过按压按键来组成单词。例如,按键 2
对应 ["a","b","c"]
,我们需要按一次键来输入 "a"
,按两次键来输入 "b"
,按三次键来输入 "c"
。
现在允许你将编号为 2
到 9
的按键重新映射到 不同 字母集合。每个按键可以映射到 任意数量 的字母,但每个字母 必须 恰好 映射到 一个 按键上。你需要找到输入字符串 word
所需的 最少 按键次数。
返回重新映射按键后输入 word
所需的 最少 按键次数。
下面给出了一种电话键盘上字母到按键的映射作为示例。注意 1
,*
,#
和 0
不 对应任何字母。
示例 1:
输入:word = "abcde"
输出:5
解释:图片中给出的重新映射方案的输入成本最小。
"a" -> 在按键 2 上按一次
"b" -> 在按键 3 上按一次
"c" -> 在按键 4 上按一次
"d" -> 在按键 5 上按一次
"e" -> 在按键 6 上按一次
总成本为 1 + 1 + 1 + 1 + 1 = 5 。
可以证明不存在其他成本更低的映射方案。
示例 2:
输入:word = "xycdefghij"
输出:12
解释:图片中给出的重新映射方案的输入成本最小。
"x" -> 在按键 2 上按一次
"y" -> 在按键 2 上按两次
"c" -> 在按键 3 上按一次
"d" -> 在按键 3 上按两次
"e" -> 在按键 4 上按一次
"f" -> 在按键 5 上按一次
"g" -> 在按键 6 上按一次
"h" -> 在按键 7 上按一次
"i" -> 在按键 8 上按一次
"j" -> 在按键 9 上按一次
总成本为 1 + 2 + 1 + 2 + 1 + 1 + 1 + 1 + 1 + 1 = 12 。
可以证明不存在其他成本更低的映射方案。
提示:
1 <= word.length <= 26
word
仅由小写英文字母组成。word
中的所有字母互不相同。
模拟
class Solution {
public int minimumPushes(String word) {
int cnt = 0;
for(char x : word.toCharArray()){
if(x == '1' || x == '*' || x == '#' || x == '0')
continue;
cnt += 1;
}
int res = 0;
int loopcnt = 1;
while(cnt > 0){
res += loopcnt * Math.min(cnt, 8);
cnt -= 8;
loopcnt += 1;
}
return res;
}
}
3015. 按距离统计房屋对数目 I
中等
给你三个 正整数 n
、x
和 y
。
在城市中,存在编号从 1
到 n
的房屋,由 n
条街道相连。对所有 1 <= i < n
,都存在一条街道连接编号为 i
的房屋与编号为 i + 1
的房屋。另存在一条街道连接编号为 x
的房屋与编号为 y
的房屋。
对于每个 k
(1 <= k <= n
),你需要找出所有满足要求的 房屋对 [house1, house2]
,即从 house1
到 house2
需要经过的 最少 街道数为 k
。
返回一个下标从 1 开始且长度为 n
的数组 result
,其中 result[k]
表示所有满足要求的房屋对的数量,即从一个房屋到另一个房屋需要经过的 最少 街道数为 k
。
注意,x
与 y
可以 相等 。
示例 1:
输入:n = 3, x = 1, y = 3
输出:[6,0,0]
解释:让我们检视每个房屋对
- 对于房屋对 (1, 2),可以直接从房屋 1 到房屋 2。
- 对于房屋对 (2, 1),可以直接从房屋 2 到房屋 1。
- 对于房屋对 (1, 3),可以直接从房屋 1 到房屋 3。
- 对于房屋对 (3, 1),可以直接从房屋 3 到房屋 1。
- 对于房屋对 (2, 3),可以直接从房屋 2 到房屋 3。
- 对于房屋对 (3, 2),可以直接从房屋 3 到房屋 2。
示例 2:
输入:n = 5, x = 2, y = 4
输出:[10,8,2,0,0]
解释:对于每个距离 k ,满足要求的房屋对如下:
- 对于 k == 1,满足要求的房屋对有 (1, 2), (2, 1), (2, 3), (3, 2), (2, 4), (4, 2), (3, 4), (4, 3), (4, 5), 以及 (5, 4)。
- 对于 k == 2,满足要求的房屋对有 (1, 3), (3, 1), (1, 4), (4, 1), (2, 5), (5, 2), (3, 5), 以及 (5, 3)。
- 对于 k == 3,满足要求的房屋对有 (1, 5),以及 (5, 1) 。
- 对于 k == 4 和 k == 5,不存在满足要求的房屋对。
示例 3:
输入:n = 4, x = 1, y = 1
输出:[6,4,2,0]
解释:对于每个距离 k ,满足要求的房屋对如下:
- 对于 k == 1,满足要求的房屋对有 (1, 2), (2, 1), (2, 3), (3, 2), (3, 4), 以及 (4, 3)。
- 对于 k == 2,满足要求的房屋对有 (1, 3), (3, 1), (2, 4), 以及 (4, 2)。
- 对于 k == 3,满足要求的房屋对有 (1, 4), 以及 (4, 1)。
- 对于 k == 4,不存在满足要求的房屋对。
提示:
2 <= n <= 100
1 <= x, y <= n
BFS
class Solution {
// 2 <= n <= 100 对每个节点跑一次bfs
public int[] countOfPairs(int n, int x, int y) {
List<Integer>[] g = new ArrayList[n];
Arrays.setAll(g, e -> new ArrayList<>());
for(int i = 0; i < n-1; i++){
g[i].add((i+1)%n);
g[(i+1)%n].add(i);
}
g[(x-1)%n].add((y-1)%n);
g[(y-1)%n].add((x-1)%n);
// 对每个节点跑一次bfs,记录最短访问次数
int[][] dis = new int[n][n];
for(int[] row : dis)
Arrays.fill(row, Integer.MAX_VALUE);
for(int i = 0; i < n; i++){
bfs(i, dis, g, n);
}
int[] res = new int[n];
for(int[] row : dis){
for(int i = 0; i < n; i++){
if(row[i] == 0) continue;
res[row[i]-1] += 1;
}
}
return res;
}
public void bfs(int starti, int[][] dis, List<Integer>[] g, int n){
boolean[] vis = new boolean[n];
dis[starti][starti] = 0;
vis[starti] = true;
Deque<Integer> dq = new ArrayDeque<>();
dq.addLast(starti);
int depth = 0;
while(!dq.isEmpty()){
depth += 1;
int size = dq.size();
while(size-- > 0){
int x = dq.pollFirst();
for(int y : g[x]){
if(!vis[y]){
vis[y] = true;
dq.addLast(y);
dis[starti][y] = depth;
}
}
}
}
return;
}
}
3016. 输入单词需要的最少按键次数 II
中等
给你一个字符串 word
,由 不同 小写英文字母组成。
电话键盘上的按键与 不同 小写英文字母集合相映射,可以通过按压按键来组成单词。例如,按键 2
对应 ["a","b","c"]
,我们需要按一次键来输入 "a"
,按两次键来输入 "b"
,按三次键来输入 "c"
。
现在允许你将编号为 2
到 9
的按键重新映射到 不同 字母集合。每个按键可以映射到 任意数量 的字母,但每个字母 必须 恰好 映射到 一个 按键上。你需要找到输入字符串 word
所需的 最少 按键次数。
返回重新映射按键后输入 word
所需的 最少 按键次数。
下面给出了一种电话键盘上字母到按键的映射作为示例。注意 1
,*
,#
和 0
不 对应任何字母。
示例 1:
输入:word = "abcde"
输出:5
解释:图片中给出的重新映射方案的输入成本最小。
"a" -> 在按键 2 上按一次
"b" -> 在按键 3 上按一次
"c" -> 在按键 4 上按一次
"d" -> 在按键 5 上按一次
"e" -> 在按键 6 上按一次
总成本为 1 + 1 + 1 + 1 + 1 = 5 。
可以证明不存在其他成本更低的映射方案。
示例 2:
输入:word = "xyzxyzxyzxyz"
输出:12
解释:图片中给出的重新映射方案的输入成本最小。
"x" -> 在按键 2 上按一次
"y" -> 在按键 3 上按一次
"z" -> 在按键 4 上按一次
总成本为 1 * 4 + 1 * 4 + 1 * 4 = 12 。
可以证明不存在其他成本更低的映射方案。
注意按键 9 没有映射到任何字母:不必让每个按键都存在与之映射的字母,但是每个字母都必须映射到按键上。
示例 3:
输入:word = "aabbccddeeffgghhiiiiii"
输出:24
解释:图片中给出的重新映射方案的输入成本最小。
"a" -> 在按键 2 上按一次
"b" -> 在按键 3 上按一次
"c" -> 在按键 4 上按一次
"d" -> 在按键 5 上按一次
"e" -> 在按键 6 上按一次
"f" -> 在按键 7 上按一次
"g" -> 在按键 8 上按一次
"h" -> 在按键 9 上按两次
"i" -> 在按键 9 上按一次
总成本为 1 * 2 + 1 * 2 + 1 * 2 + 1 * 2 + 1 * 2 + 1 * 2 + 1 * 2 + 2 * 2 + 6 * 1 = 24 。
可以证明不存在其他成本更低的映射方案。
提示:
1 <= word.length <= 105
word
仅由小写英文字母组成。
贪心
class Solution {
/**
频率越高的字母单击应该次数越少
*/
public int minimumPushes(String word) {
Integer[] cnt = new Integer[26];
Arrays.fill(cnt, 0);
for(char x : word.toCharArray()){
if(x == '1' || x == '*' || x == '#' || x == '0')
continue;
cnt[x - 'a'] += 1;
}
Arrays.sort(cnt, (a, b) -> b - a);
int res = 0;
int number = 0;
for(int x : cnt){
if(x > 0){
res += x * (number / 8 + 1);
number += 1;
}
}
return res;
}
}
3017. 按距离统计房屋对数目 II
困难
给你三个 正整数 n
、x
和 y
。
在城市中,存在编号从 1
到 n
的房屋,由 n
条街道相连。对所有 1 <= i < n
,都存在一条街道连接编号为 i
的房屋与编号为 i + 1
的房屋。另存在一条街道连接编号为 x
的房屋与编号为 y
的房屋。
对于每个 k
(1 <= k <= n
),你需要找出所有满足要求的 房屋对 [house1, house2]
,即从 house1
到 house2
需要经过的 最少 街道数为 k
。
返回一个下标从 1 开始且长度为 n
的数组 result
,其中 result[k]
表示所有满足要求的房屋对的数量,即从一个房屋到另一个房屋需要经过的 最少 街道数为 k
。
注意,x
与 y
可以 相等 。
示例 1:
输入:n = 3, x = 1, y = 3
输出:[6,0,0]
解释:让我们检视每个房屋对
- 对于房屋对 (1, 2),可以直接从房屋 1 到房屋 2。
- 对于房屋对 (2, 1),可以直接从房屋 2 到房屋 1。
- 对于房屋对 (1, 3),可以直接从房屋 1 到房屋 3。
- 对于房屋对 (3, 1),可以直接从房屋 3 到房屋 1。
- 对于房屋对 (2, 3),可以直接从房屋 2 到房屋 3。
- 对于房屋对 (3, 2),可以直接从房屋 3 到房屋 2。
示例 2:
输入:n = 5, x = 2, y = 4
输出:[10,8,2,0,0]
解释:对于每个距离 k ,满足要求的房屋对如下:
- 对于 k == 1,满足要求的房屋对有 (1, 2), (2, 1), (2, 3), (3, 2), (2, 4), (4, 2), (3, 4), (4, 3), (4, 5), 以及 (5, 4)。
- 对于 k == 2,满足要求的房屋对有 (1, 3), (3, 1), (1, 4), (4, 1), (2, 5), (5, 2), (3, 5), 以及 (5, 3)。
- 对于 k == 3,满足要求的房屋对有 (1, 5),以及 (5, 1) 。
- 对于 k == 4 和 k == 5,不存在满足要求的房屋对。
示例 3:
输入:n = 4, x = 1, y = 1
输出:[6,4,2,0]
解释:对于每个距离 k ,满足要求的房屋对如下:
- 对于 k == 1,满足要求的房屋对有 (1, 2), (2, 1), (2, 3), (3, 2), (3, 4), 以及 (4, 3)。
- 对于 k == 2,满足要求的房屋对有 (1, 3), (3, 1), (2, 4), 以及 (4, 2)。
- 对于 k == 3,满足要求的房屋对有 (1, 4), 以及 (4, 1)。
- 对于 k == 4,不存在满足要求的房屋对。
提示:
2 <= n <= 105