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

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

相关推荐
ideaout技术团队3 小时前
leetcode学习笔记2:多数元素(摩尔投票算法)
学习·算法·leetcode
代码充电宝3 小时前
LeetCode 算法题【简单】283. 移动零
java·算法·leetcode·职场和发展
不枯石5 小时前
Matlab通过GUI实现点云的均值滤波(附最简版)
开发语言·图像处理·算法·计算机视觉·matlab·均值算法
不枯石6 小时前
Matlab通过GUI实现点云的双边(Bilateral)滤波(附最简版)
开发语言·图像处理·算法·计算机视觉·matlab
白水先森7 小时前
C语言作用域与数组详解
java·数据结构·算法
想唱rap8 小时前
直接选择排序、堆排序、冒泡排序
c语言·数据结构·笔记·算法·新浪微博
老葱头蒸鸡9 小时前
(27)APS.NET Core8.0 堆栈原理通俗理解
算法
视睿9 小时前
【C++练习】06.输出100以内的所有素数
开发语言·c++·算法·机器人·无人机
柠檬071110 小时前
matlab cell 数据转换及记录
算法
YuTaoShao10 小时前
【LeetCode 每日一题】2221. 数组的三角和
数据结构·算法·leetcode