(A卷,100分)- 最多颜色的车辆(Java & JS & Python)

题目描述

在一个狭小的路口,每秒只能通过一辆车,假设车辆的颜色只有 3 种,找出 N 秒内经过的最多颜色的车辆数量。

三种颜色编号为0 ,1 ,2

输入描述

第一行输入的是通过的车辆颜色信息

[0,1,1,2] 代表4 秒钟通过的车辆颜色分别是 0 , 1 , 1 , 2

第二行输入的是统计时间窗,整型,单位为秒

输出描述

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

用例

输入 0 1 2 1
3
输出 2
说明 在 3 秒时间窗内,每个颜色最多出现 2 次。例如:[1,2,1]
输入 0 1 2 1
2
输出 1
说明 在 2 秒时间窗内,每个颜色最多出现1 次。

题目解析

简单的滑动窗口应用。我们可以利用相邻两个滑窗的差异比较,来避免重复的计算。

比如:下图是用例1的滑窗(黄色部分)运动过程

 第二个滑窗相较于第一个滑窗而言,失去了0,新增了1,因此我们不需要重新统计第二个滑窗内部各种颜色的数量,只需要在第一个滑窗的统计结果基础上,减少0颜色数量1个,增加1颜色数量1个即可。


2023.03.31 根据考友反馈,本题会出现不止3种颜色,可能出现多种颜色,因此代码需要解除颜色限制。

下面代码已更新。

JavaScript算法源码

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

const lines = [];
rl.on("line", (line) => {
  lines.push(line);

  if (lines.length === 2) {
    const arr = lines[0].split(" ");
    const n = parseInt(lines[1]);

    console.log(getResult(arr, n));

    lines.length = 0;
  }
});

function getResult(arr, n) {
  // count用于统计滑动窗口内各种颜色的数目
  const count = {};

  // 初始滑动窗口的左右边界,注意这里的右边界r是不包含了,为了方便后面进行slice
  let l = 0;
  let r = l + n;

  // 统计初始滑动窗口中各种颜色的数量
  arr.slice(l, r).forEach((c) => {
    if (!count[c]) count[c] = 0;
    count[c]++;
  });

  // 将初始滑动窗口内部最多颜色数量给max
  let max = Math.max.apply(null, Object.values(count));

  // 如果滑动窗口右边界未达到数组尾巴,就继续右移
  // 注意,初始滑窗的右边界r是不包含的,因此r可以直接当成下一个滑窗的右边界使用
  while (r < arr.length) {
    // 当滑动窗口右移后,新的滑动窗口相比移动前来看,新增了arr[r],失去了arr[l],注意此时左边界l还是指向上一个滑窗的左边界,而不是新滑窗的左边界,因此可以直接通过arr[l]取得失去的
    const add = arr[r++];
    const remove = arr[l++];

    if (!count[add]) count[add] = 0;
    count[add]++;

    if (!count[remove]) count[remove] = 0;
    count[remove]--;

    // 只有新增数量的颜色可能突破最大值
    max = Math.max(max, count[add]);
  }

  return max;
}

Java算法源码

import java.util.Arrays;
import java.util.HashMap;
import java.util.Scanner;

public class Main {
  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    Integer[] arr =
        Arrays.stream(sc.nextLine().split(" ")).map(Integer::parseInt).toArray(Integer[]::new);
    int n = sc.nextInt();

    System.out.println(getResult(arr, n));
  }

  public static int getResult(Integer[] arr, int n) {
    // count用于统计滑动窗口内各种颜色的数目
    HashMap<Integer, Integer> count = new HashMap<>();

    // 初始滑动窗口的左右边界,注意这里的右边界r是不包含的
    int l = 0;
    int r = l + n;

    // 记录滑窗内部最多颜色数量
    int max = 0;

    // 统计初始滑动窗口中各种颜色的数量
    for (int i = l; i < Math.min(r, arr.length); i++) {
      Integer c = arr[i];
      count.put(c, count.getOrDefault(c, 0) + 1);
      max = Math.max(max, count.get(c));
    }

    // 如果滑动窗口右边界未达到数组尾巴,就继续右移
    // 注意,初始滑窗的右边界r是不包含的,因此r可以直接当成下一个滑窗的右边界使用
    while (r < arr.length) {
      // 当滑动窗口右移后,新的滑动窗口相比移动前来看,新增了arr[r],失去了arr[l],注意此时左边界l还是指向上一个滑窗的左边界,而不是新滑窗的左边界,因此可以直接通过arr[l]取得失去的
      Integer add = arr[r++];
      Integer remove = arr[l++];

      count.put(add, count.getOrDefault(add, 0) + 1);
      count.put(remove, count.getOrDefault(remove, 0) - 1);

      // 只有新增数量的颜色可能突破最大值
      max = Math.max(max, count.get(add));
    }

    return max;
  }
}

Python算法源码

# 输入获取
arr = input().split()
n = int(input())


# 算法入口
def getResult(arr, n):
    count = {}

    l = 0
    r = l + n

    for c in arr[l:r]:
        if count.get(c) is None:
            count[c] = 0
        count[c] += 1

    maxV = max(count.values())

    while r < len(arr):
        add = arr[r]
        remove = arr[l]

        r += 1
        l += 1

        if count.get(add) is None:
            count[add] = 0
        count[add] += 1

        if count.get(remove) is None:
            count[remove] = 0
        count[remove] -= 1

        maxV = max(maxV, count[add])

    return maxV


# 算法调用
print(getResult(arr, n))

免责声明:

1、IT资源小站为非营利性网站,全站所有资料仅供网友个人学习使用,禁止商用
2、本站所有文档、视频、书籍等资料均由网友分享,本站只负责收集不承担任何技术及版权问题
3、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除下载链接并致以最深的歉意
4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
5、一经注册为本站会员,一律视为同意网站规定,本站管理员及版主有权禁止违规用户
6、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和IT资源小站的同意
7、IT资源小站管理员和版主有权不事先通知发贴者而删除本文

0

评论0

站点公告

没有账号?注册  忘记密码?