【华为OD】找出通过车辆最多颜色

文章目录

【华为OD】找出通过车辆最多颜色

题目描述

在一个狭小的路口,每秒只能通过一辆车,假如车辆的颜色只有3种,找出N秒内经过的最多颜色的车辆数量,三种颜色编号为0, 1, 2。

输入

第一行输入的是通过的车辆颜色信息。比如0,1,1,2 代表4秒钟通过的车辆颜色分别是0, 1, 1, 2 第二行输入的是统计时间窗,整型,单位为秒。

输出

输出指定时间窗内经过的最多颜色的车辆数量

示例一

输入:

复制代码
0 1 2 1
3

输出:

复制代码
2

说明:

1,2,1 这个3秒时间窗内,1这个颜色出现2次,数量最多

示例二

输入:

复制代码
0 1 2 1
2

输出:

复制代码
1

说明:

在2秒时间窗内,每个颜色最多出现1次

解题思路

这是一个典型的滑动窗口问题。我们需要在给定的时间窗口内,找出出现次数最多的颜色的数量。

核心思路:

  1. 使用滑动窗口遍历所有可能的时间窗口
  2. 对每个窗口内的颜色进行计数
  3. 找出每个窗口中出现次数最多的颜色
  4. 返回所有窗口中的最大值

解法一:暴力解法

思路

对每个可能的窗口位置,统计窗口内每种颜色的出现次数,找出最大值。

Java实现
java 复制代码
import java.util.*;

public class Solution1 {
    public static int findMaxColorCount(int[] cars, int windowSize) {
        int n = cars.length;
        int maxCount = 0;
        
        // 遍历所有可能的窗口起始位置
        for (int i = 0; i <= n - windowSize; i++) {
            // 统计当前窗口内每种颜色的数量
            int[] colorCount = new int[3]; // 0, 1, 2三种颜色
            
            for (int j = i; j < i + windowSize; j++) {
                colorCount[cars[j]]++;
            }
            
            // 找出当前窗口内最多的颜色数量
            int currentMax = Math.max(colorCount[0], Math.max(colorCount[1], colorCount[2]));
            maxCount = Math.max(maxCount, currentMax);
        }
        
        return maxCount;
    }
    
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String[] input = scanner.nextLine().split(" ");
        int[] cars = new int[input.length];
        for (int i = 0; i < input.length; i++) {
            cars[i] = Integer.parseInt(input[i]);
        }
        int windowSize = scanner.nextInt();
        
        System.out.println(findMaxColorCount(cars, windowSize));
    }
}
Python实现
python 复制代码
def find_max_color_count(cars, window_size):
    n = len(cars)
    max_count = 0
    
    # 遍历所有可能的窗口起始位置
    for i in range(n - window_size + 1):
        # 统计当前窗口内每种颜色的数量
        color_count = [0, 0, 0]  # 0, 1, 2三种颜色
        
        for j in range(i, i + window_size):
            color_count[cars[j]] += 1
        
        # 找出当前窗口内最多的颜色数量
        current_max = max(color_count)
        max_count = max(max_count, current_max)
    
    return max_count

# 输入处理
cars = list(map(int, input().split()))
window_size = int(input())

print(find_max_color_count(cars, window_size))
C++实现
cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>
#include <sstream>
using namespace std;

int findMaxColorCount(vector<int>& cars, int windowSize) {
    int n = cars.size();
    int maxCount = 0;
    
    // 遍历所有可能的窗口起始位置
    for (int i = 0; i <= n - windowSize; i++) {
        // 统计当前窗口内每种颜色的数量
        vector<int> colorCount(3, 0); // 0, 1, 2三种颜色
        
        for (int j = i; j < i + windowSize; j++) {
            colorCount[cars[j]]++;
        }
        
        // 找出当前窗口内最多的颜色数量
        int currentMax = *max_element(colorCount.begin(), colorCount.end());
        maxCount = max(maxCount, currentMax);
    }
    
    return maxCount;
}

int main() {
    string line;
    getline(cin, line);
    istringstream iss(line);
    vector<int> cars;
    int num;
    while (iss >> num) {
        cars.push_back(num);
    }
    
    int windowSize;
    cin >> windowSize;
    
    cout << findMaxColorCount(cars, windowSize) << endl;
    
    return 0;
}

解法二:滑动窗口优化

思路

使用滑动窗口技术,避免重复计算。当窗口向右移动时,只需要移除左边的元素,添加右边的元素。

Java实现
java 复制代码
import java.util.*;

public class Solution2 {
    public static int findMaxColorCount(int[] cars, int windowSize) {
        int n = cars.length;
        if (windowSize > n) return 0;
        
        int maxCount = 0;
        int[] colorCount = new int[3]; // 0, 1, 2三种颜色
        
        // 初始化第一个窗口
        for (int i = 0; i < windowSize; i++) {
            colorCount[cars[i]]++;
        }
        
        // 计算第一个窗口的最大值
        maxCount = Math.max(colorCount[0], Math.max(colorCount[1], colorCount[2]));
        
        // 滑动窗口
        for (int i = windowSize; i < n; i++) {
            // 移除窗口左边的元素
            colorCount[cars[i - windowSize]]--;
            // 添加窗口右边的元素
            colorCount[cars[i]]++;
            
            // 更新最大值
            int currentMax = Math.max(colorCount[0], Math.max(colorCount[1], colorCount[2]));
            maxCount = Math.max(maxCount, currentMax);
        }
        
        return maxCount;
    }
    
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String[] input = scanner.nextLine().split(" ");
        int[] cars = new int[input.length];
        for (int i = 0; i < input.length; i++) {
            cars[i] = Integer.parseInt(input[i]);
        }
        int windowSize = scanner.nextInt();
        
        System.out.println(findMaxColorCount(cars, windowSize));
    }
}
Python实现
python 复制代码
def find_max_color_count(cars, window_size):
    n = len(cars)
    if window_size > n:
        return 0
    
    max_count = 0
    color_count = [0, 0, 0]  # 0, 1, 2三种颜色
    
    # 初始化第一个窗口
    for i in range(window_size):
        color_count[cars[i]] += 1
    
    # 计算第一个窗口的最大值
    max_count = max(color_count)
    
    # 滑动窗口
    for i in range(window_size, n):
        # 移除窗口左边的元素
        color_count[cars[i - window_size]] -= 1
        # 添加窗口右边的元素
        color_count[cars[i]] += 1
        
        # 更新最大值
        current_max = max(color_count)
        max_count = max(max_count, current_max)
    
    return max_count

# 输入处理
cars = list(map(int, input().split()))
window_size = int(input())

print(find_max_color_count(cars, window_size))
C++实现
cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>
#include <sstream>
using namespace std;

int findMaxColorCount(vector<int>& cars, int windowSize) {
    int n = cars.size();
    if (windowSize > n) return 0;
    
    int maxCount = 0;
    vector<int> colorCount(3, 0); // 0, 1, 2三种颜色
    
    // 初始化第一个窗口
    for (int i = 0; i < windowSize; i++) {
        colorCount[cars[i]]++;
    }
    
    // 计算第一个窗口的最大值
    maxCount = *max_element(colorCount.begin(), colorCount.end());
    
    // 滑动窗口
    for (int i = windowSize; i < n; i++) {
        // 移除窗口左边的元素
        colorCount[cars[i - windowSize]]--;
        // 添加窗口右边的元素
        colorCount[cars[i]]++;
        
        // 更新最大值
        int currentMax = *max_element(colorCount.begin(), colorCount.end());
        maxCount = max(maxCount, currentMax);
    }
    
    return maxCount;
}

int main() {
    string line;
    getline(cin, line);
    istringstream iss(line);
    vector<int> cars;
    int num;
    while (iss >> num) {
        cars.push_back(num);
    }
    
    int windowSize;
    cin >> windowSize;
    
    cout << findMaxColorCount(cars, windowSize) << endl;
    
    return 0;
}

复杂度分析

解法一(暴力解法)

  • 时间复杂度:O(n × m),其中n是车辆数组长度,m是窗口大小
  • 空间复杂度:O(1),只使用了固定大小的数组

解法二(滑动窗口)

  • 时间复杂度:O(n),其中n是车辆数组长度
  • 空间复杂度:O(1),只使用了固定大小的数组

总结

这道题考查的是滑动窗口的经典应用。解法二通过优化避免了重复计算,将时间复杂度从O(n×m)降低到O(n),在处理大数据量时效果更佳。

关键点:

  1. 理解滑动窗口的概念
  2. 正确处理窗口边界
  3. 高效地维护窗口内的统计信息

这类问题在实际开发中经常遇到,掌握滑动窗口技巧对解决类似问题很有帮助。

相关推荐
先吃饱再说11 小时前
判断回文字符串,从一行代码到双指针优化
算法
黄敬峰13 小时前
深入理解算法核心:从递归思想、数组扁平化到快速排序
算法
得物技术15 小时前
从狂野代码到按目标生产:得物推荐 AI Harness 的工程化实践|AICon 演讲整理
人工智能·算法·架构
AI小老六18 小时前
SkillOpt 架构拆解:把 Skill 文本当参数,用执行轨迹训练 Agent
后端·算法·ai编程
胡萝卜术19 小时前
从“分数打架”到“排名投票”:为什么你的ChatBI必须用RRF?
算法·设计模式·面试
Asize19 小时前
初识DFS 与 BFS:递归、队列与图遍历
算法
罗西的思考1 天前
机器人 / 强化学习】HIL-SERL:人类在环驱动的具身智能进化框架
人工智能·算法·机器学习
美团技术团队2 天前
LongCat 开源 VitaBench 2.0:长期动态智能体基准新标杆
人工智能·算法
To_OC2 天前
LC 207 课程表:刚学图论那会儿,我连这是拓扑排序都没看出来
javascript·算法·leetcode