👨⚕️ 主页: gis分享者
👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅!
👨⚕️ 收录于专栏:华为OD面试

文章目录
- 一、🍀前言
-
- [1.1 ☘️题目详情](#1.1 ☘️题目详情)
- [1.2 ☘️参考解题答案](#1.2 ☘️参考解题答案)
一、🍀前言
2023A卷,找出通过车辆最多颜色。
1.1 ☘️题目详情
题目:
在一个狭小的路口,每秒只能通过一辆车,假如车辆的颜色只有 3 种,找出 N 秒内经过的最多颜色的车辆数量,三种颜色编号为 0, 1, 2。
输入:
第一行输入的是通过的车辆颜色信息。比如[0, 1, 1, 2] 代表 4 秒钟通过的车辆颜色分别是 0, 1, 1, 2第二行输入的是统计时间窗,整型,单位为秒。
输出:
输出指定时间窗内经过的最多颜色的车辆数量。
示例一:
javascript
// 输入
0 1 2 1
3
// 输出
2
// 说明 在[1,2,1]这个 3 秒时间窗内,1 这个颜色出现 2 次,数量最多
示例二:
javascript
// 输入
0 1 2 1
2
// 输出
1
// 说明 在 2 秒时间窗内,每个颜色最多出现 1 次
1.2 ☘️参考解题答案
解题思路
本题明确地指出,时间窗口的长度为N,所以考虑使用固定滑窗来解决问题。
由于在滑窗内需要统计各种颜色车辆的数目,所以我们可以用哈希表来统计元素频率。特别地,由于题目告诉我们车辆颜色有且只有 0, 1, 2 三种,所以我们可以更加简单地用一个列表 windows_colors 来代替哈希表。
对于固定滑窗,我们需要考虑滑窗和答案的初始化。我们需要以第一个窗口,即colors[0:N]这个窗口的情况来初始化windows_colors = [0, 0, 0]。然后遍历colors[0:N]中的颜色,将其统计在windows_colors中。而答案变量ans的初始化,即为为第一个固定滑窗中的最大值。
然后我们思考滑窗三问三答。
滑窗三问
**Q1:**对于每一个右指针right所指的元素right_color,做什么操作?
**Q2:**什么时候要令左指针left右移?对于left所指的元素left_color,要做什么操作?
**Q3:**什么时候进行ans的更新?如何更新?
滑窗三答
**A1:**将right_color在windows_colors中的统计次数+1
**A2:**在固定滑窗中,left始终为right-N,同时需要将left_color在windows_colors中的统计次数-1
**A3:**做完windows_colors的更新后,取其中最大值和当前ans比较并更新。
Python实现:
python
# 题目:2023Q1A-找出通过车辆最多颜色
# 分值:100
# 作者:闭着眼睛学数理化
# 算法:固定滑窗
# 代码看不懂的地方,请直接在群上提问
colors = list(map(int, input().split()))
N = int(input())
# 初始化统计时间窗口内各种颜色出现的次数的列表
# windows_colors[i]表示颜色为i的车辆的个数
windows_colors = [0, 0, 0]
# 初始化固定滑窗中的颜色数目
for color in colors[:N]:
windows_colors[color] += 1
# 初始化答案变量,为第一个固定滑窗中的最大值
ans = max(windows_colors)
for right, right_color in enumerate(colors[N:], N):
# Q1:对于每一个右指针right所指的元素right_color,做什么操作?
# A1:将right_color在窗口中的统计次数+1
windows_colors[right_color] += 1
# Q2:什么时候要令左指针left右移?
# 对于left所指的元素left_color,要做什么操作?
# A2:在固定滑窗中,left始终为right-N
# 将left_color在窗口中的统计次数-1
left = right - N
left_color = colors[left]
windows_colors[left_color] -= 1
# A3:什么时候进行ans的更新?
# Q3:做完windows_colors的更新后,取其中最大值和当前ans比较并更新
ans = max(ans, max(windows_colors))
print(ans)
c++实现:
cpp
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
int main() {
string line;
getline(cin, line);
istringstream iss(line);
vector<int> colors;
int color;
while (iss >> color) {
colors.push_back(color);
}
int n;
cin >> n;
int arr[3] = {0, 0, 0};
int ans = 0;
int cur = 0;
if (n > colors.size()) {
n = colors.size();
}
for (int i = 0; i < n; i++) {
int num = colors[i];
arr[num]++;
}
cur = max(arr[0], max(arr[1], arr[2]));
ans = max(ans, cur);
for (int right = n; right < colors.size(); right++) {
int num = colors[right];
arr[num]++;
int leftNum = colors[right - n];
arr[leftNum]--;
ans = max(ans, arr[num]);
}
cout << ans << endl;
return 0;
}
java实现:
java
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner s = new Scanner(System.in);
String[] str = s.nextLine().split(" ");
int n = s.nextInt();
int[] arr = new int[3];
int max = 0;
int cur = 0;
if(n > str.length){
n = str.length;
}
for(int i = 0;i < n;i++){
int num = str[i].charAt(0)-'0';
arr[num]++;
}
cur = Math.max(Math.max(arr[0],arr[1]),arr[2]);
max = Math.max(max,cur);
for(int right = n;right < str.length;right++){
int num = str[right].charAt(0)-'0';
arr[num]++;
int left = str[right-n].charAt(0)-'0';
arr[left]--;
max = Math.max(max,arr[num]);
}
System.out.println(max);
}
}
时空复杂度
时间复杂度:O(M)。仅需一次遍历数组,M为数组长度。
空间复杂度:O(1)。列表的长度为3,为常数级别空间。