【华为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. 高效地维护窗口内的统计信息

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

相关推荐
塔中妖3 小时前
【华为OD】环中最长子串2
算法·华为od
JCBP_3 小时前
QT(3)
开发语言·汇编·c++·qt·算法
研梦非凡3 小时前
ICCV 2025|基于曲线感知高斯溅射的3D参数曲线重建
人工智能·算法·3d
XFF不秃头3 小时前
力扣刷题笔记-三数之和
c++·笔记·算法·leetcode
一碗白开水一4 小时前
【第19话:定位建图】SLAM点云配准之3D-3D ICP(Iterative Closest Point)方法详解
人工智能·算法
编码浪子4 小时前
趣味学RUST基础篇(函数式编程闭包)
开发语言·算法·rust
Want5954 小时前
C/C++圣诞树②
c语言·c++·算法
索迪迈科技5 小时前
算法题(203):矩阵最小路径和
线性代数·算法·矩阵
默默无名的大学生5 小时前
数据结构——链表的基本操作
数据结构·算法