华为OD机试 新系统 统一考试题库清单持续收录中以及考点说明Python/JS/C/C。专栏导读本专栏收录于《华为OD机试真题Python/JS/C/C》。刷的越多抽中的概率越大私信哪吒备注华为OD加入华为OD刷题交流群每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景发现新题目随时更新。一、题目描述某智慧园区管理系统记录了 N 个连续的能源使用时段每个时段使用的能源类型用整数表示1太阳能2风能3电能4天然气5地热能。为了优化能源配置管理员需要分析在这 N 个时段中连续使用不超过 2 种能源的最长时段长度是多少请编写程序计算这个最大长度。二、输入描述输入是一个整数数组表示各时段的能源类型数组元素1太阳能2风能3电能4天然气5地热能约束条件1 ≤ 数组长度 ≤ 100000能源类型为 1-5 的整数三、输出描述输出最长连续时段的长度。补充说明如果输入为空则输出 0四、测试用例测试用例11、输入1,2,1,2,3,2,2,22、输出5测试用例21、输入1,2,3,4,52、输出2五、解题思路使用两个指针 left、right 表示当前连续区间right 不断向右移动把新的能源类型加入窗口。使用计数数组 count 统计当前窗口中每种能源出现次数。distinct 表示当前窗口中不同能源类型的数量。如果 distinct 2说明窗口不满足条件不断移动 left删除左端能源直到窗口重新只包含不超过 2 种能源每次窗口合法后使用right - left 1更新最长长度。六、Python算法源码importsys# 读取控制台的一行输入并去掉首尾空白和换行linesys.stdin.readline().strip()# 输入为空时根据题意直接输出0ifnotline:print(0)sys.exit(0)# Java中使用 split(,)这里保持相同逻辑# 按英文逗号分隔然后把每一个字符串转换成整数nums[int(x)forxinline.split(,)] 能源类型只有1~5因此使用长度为6的数组进行计数。 count[i] 表示当前滑动窗口中能源类型 i 出现的次数。 下标0不使用。 count[0]*6# 滑动窗口左边界left0# 当前窗口中不同能源类型的数量distinct0# 保存最长合法连续区间长度max_len0# right作为滑动窗口右边界不断向右扩展forrightinrange(len(nums)):energy_typenums[right] 如果这种能源当前没有出现在窗口中 那么加入它之后窗口中的能源种类数需要加1。 ifcount[energy_type]0:distinct1count[energy_type]1 如果窗口中的不同能源超过2种 就不断移动左边界缩小窗口。 直到窗口重新满足“最多包含2种能源”。 whiledistinct2:left_typenums[left]count[left_type]-1 如果这种能源的计数变成0 说明该能源已经完全退出当前窗口 因此不同能源种类数减1。 ifcount[left_type]0:distinct-1left1 while结束后当前[left, right]窗口一定合法 使用当前窗口长度更新最大值。 max_lenmax(max_len,right-left1)print(max_len)七、JavaScript算法源码constfsrequire(fs);// 读取标准输入只取第一行与Java的scanner.nextLine()保持一致constinputfs.readFileSync(0,utf8).split(/\r?\n/)[0].trim();// 输入为空时直接输出0if(input.length0){console.log(0);process.exit(0);}// 按英文逗号分隔然后将字符串转换成数字constnumsinput.split(,).map(Number);/* * 能源类型只有1~5因此使用长度为6的数组。 * count[i]表示当前滑动窗口中能源类型i出现的次数。 */constcountnewArray(6).fill(0);// 滑动窗口左边界letleft0;// 当前窗口中不同能源类型数量letdistinct0;// 最长合法连续区间长度letmaxLen0;// right不断向右扩展滑动窗口for(letright0;rightnums.length;right){consttypenums[right];/* * 如果当前能源在窗口中的数量为0 * 说明它是一个新的能源种类因此distinct加1。 */if(count[type]0){distinct;}count[type];/* * 如果当前窗口已经包含超过2种能源 * 就不断移动left缩小窗口 * 直到窗口重新只包含不超过2种能源。 */while(distinct2){constleftTypenums[left];count[leftType]--;/* * 如果某种能源的数量已经变成0 * 说明这种能源已经完全退出当前窗口。 */if(count[leftType]0){distinct--;}left;}/* * 此时窗口[left, right]一定满足题目条件 * 更新当前找到的最长连续区间长度。 */maxLenMath.max(maxLen,right-left1);}console.log(maxLen);八、C算法源码#includestdio.h#includestdlib.h#includestring.h#defineMAX_N100000#defineMAX_LINE1000000intmain(void){// 保存控制台输入的一整行charline[MAX_LINE];/* * fgets读取一整行。 * 如果没有读取到任何内容则按照题意输出0。 */if(fgets(line,sizeof(line),stdin)NULL){printf(0\n);return0;}// 去除输入末尾可能存在的 \n 或 \r\nline[strcspn(line,\r\n)]\0;// 空行输入直接输出0if(line[0]\0){printf(0\n);return0;}// 根据题目约束数组最大长度为100000intnums[MAX_N];intn0;/* * Java使用split(,)进行分割。 * C语言中使用strtok按照英文逗号分割字符串。 */char*tokenstrtok(line,,);while(token!NULLnMAX_N){// atoi将数字字符串转换成整数nums[n]atoi(token);// 继续取得下一个逗号分隔的数据tokenstrtok(NULL,,);}if(n0){printf(0\n);return0;}/* * 能源类型只有1~5。 * count[i]表示当前滑动窗口中能源类型i出现的次数。 */intcount[6]{0};// 滑动窗口左边界intleft0;// 当前窗口中不同能源类型数量intdistinct0;// 最大连续区间长度intmaxLen0;// right不断向右扩展窗口for(intright0;rightn;right){inttypenums[right];/* * 如果该能源当前没有出现在窗口中 * 加入之后窗口的能源种类数增加1。 */if(count[type]0){distinct;}count[type];/* * 当前窗口超过2种能源时 * 不断移动左边界缩小窗口。 */while(distinct2){intleftTypenums[left];count[leftType]--;/* * 如果这种能源出现次数变成0 * 说明它已经彻底离开当前窗口 * 不同能源数量减1。 */if(count[leftType]0){distinct--;}left;}/* * while循环结束后当前窗口一定满足条件 * 计算窗口长度并更新最大值。 */intcurrentLenright-left1;if(currentLenmaxLen){maxLencurrentLen;}}printf(%d\n,maxLen);return0;}九、C算法源码#includeiostream#includesstream#includestring#includevector#includealgorithmusingnamespacestd;intmain(){string line;/* * getline读取一整行 * 与Java中的scanner.nextLine()作用相似。 */if(!getline(cin,line)||line.empty()){cout0\n;return0;}vectorintnums;string token;stringstreamss(line);/* * 使用getline并指定,作为分隔符 * 对应Java中的split(,)。 */while(getline(ss,token,,)){// stoi将字符串转换成整数nums.push_back(stoi(token));}if(nums.empty()){cout0\n;return0;}/* * 能源类型只有1~5 * count[i]表示当前滑动窗口中能源类型i出现的次数。 */intcount[6]{0};// 滑动窗口左边界intleft0;// 当前窗口不同能源类型数量intdistinct0;// 最长合法区间intmaxLen0;// right不断向右移动扩大窗口for(intright0;rightstatic_castint(nums.size());right){inttypenums[right];/* * 如果这种能源原来没有出现在窗口中 * 加入它后能源种类数增加1。 */if(count[type]0){distinct;}count[type];/* * 如果窗口出现超过2种能源 * 不断从窗口左侧删除元素 * 直到窗口重新合法。 */while(distinct2){intleftTypenums[left];count[leftType]--;/* * 如果某种能源数量变成0 * 表示这种能源已经完全退出当前窗口。 */if(count[leftType]0){distinct--;}left;}/* * 此时[left, right]是一个满足条件的窗口 * 更新最大连续区间长度。 */maxLenmax(maxLen,right-left1);}coutmaxLen\n;return0;}下一篇华为OD机试真题 - 简易内存池Python/JS/C/C 新系统 200分本文收录于华为OD机试真题Python/JS/C/C刷的越多抽中的概率越大私信哪吒备注华为OD加入华为OD刷题交流群每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景发现新题目随时更新。