迅雷笔试 最长相等子段数列长度 滑动窗口

👨‍🏫 牛马Code:最长相等子段数列长度
在这里插入图片描述

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashMap;

public class Main
{
	// 创建一个输入流读取器,用于读取控制台输入
	static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

	public static void main(String[] args) throws Exception
	{
		// 读取一行输入并按空格分割成字符串数组
		String[] ss = in.readLine().split(" ");
		// 将字符串数组转换成整数数组
		int[] nums = Arrays.stream(ss).mapToInt(Integer::parseInt).toArray();

		// 初始化变量
		int max = 0; // 当前窗口中出现次数最多的数字的出现次数
		int l = 0; // 窗口的左边界
		int r = 0; // 窗口的右边界
		int replaceCnt = 3; // 可替换次数,即最多可以替换3次
		HashMap<Integer, Integer> map = new HashMap<>(); // 记录窗口内每个数字的出现次数
		int ans = 0; // 记录最长相等子段的长度

		// 开始滑动窗口
		while (r < ss.length)
		{
			// 将当前窗口右边界数字加入map,并更新其出现次数
			map.put(nums[r], map.getOrDefault(nums[r], 0) + 1);
			// 更新当前窗口内出现次数最多的数字的最大次数
			max = Math.max(max, map.get(nums[r]));

			// 当窗口内需要替换的次数超过了允许的替换次数(replaceCnt)时,调整窗口左边界
			while ((r - l + 1) - max > replaceCnt)
			{
				// 取出窗口左边界数字的出现次数
				int t = map.get(nums[l]) - 1;
				// 如果次数为0,移除该数字
				if (t == 0)
				{
					map.remove(nums[l]);
				} else
				{
					// 否则更新该数字的次数
					map.put(nums[l], t);
				}
				// 左边界右移
				l++;
			}

			// 右边界右移
			r++;
			// 更新最长相等子段的长度
			if (r - l >= ans)
				ans = r - l;
		}

		// 输出最长相等子段的长度
		System.out.println(ans);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值