当前位置: 首页 > article >正文

华为OD机试 - 阿里巴巴找黄金宝箱(V) - 滑动窗口(Python/JS/C/C++ 2024 E卷 100分)

在这里插入图片描述

华为OD机试 2024E卷题库疯狂收录中,刷题点这里

专栏导读

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

一、题目描述

一贫如洗的樵夫阿里巴巴在去砍柴的路上,无意中发现了强盗集团的藏宝地,藏宝地有编号从0~N的箱子,每个箱子上面贴有一个数字。

阿里巴巴牢记出一个咒语数字k(k<N),找出连续k个宝箱数字和的最大值,并输出该最大值。

二、输入描述

第一行输入一个数字字符串,数字之间使用逗号分隔,例如:2,10,-3,-8,40,5

• 1 ≤ 字串中数字的个数 ≤ 100000

• -10000 ≤ 每个数字 ≤ 10000

第二行输入咒语数字,例如:4,咒语数字大小小于宝箱的个数

三、输出描述

连续k个宝箱数字和的最大值,例如:39

四、测试用例

测试用例1:

1、输入

2,10,-3,-8,40,5
4

2、输出

39

3、说明

初始窗口为 2,10,-3,-8,和为 1。
移动窗口,接下来是 10,-3,-8,40,和为 39,更新最大和。
接下来窗口为 -3,-8,40,5,和为 34,保持最大和为 39。

测试用例2:

1、输入

8
1

2、输出

8

3、说明

只有一个数字,窗口大小为 1,直接输出该数字 8。

测试用例3:

1、输入

-1,-2,-3,-4
2

2、输出

-3

3、说明

初始窗口为 -1,-2,和为 -3。
后续窗口的和分别为 -5 和 -7,因此最大和保持为 -3。

五、解题思路

1、为什么采用滑动窗口?

在这个问题中,我们需要找到一组连续的 k 个数字的最大和。直接采用暴力算法虽然可以解决问题,但其时间复杂度较高,尤其是在数组较大时,效率会非常低下。

滑动窗口技术特别适合以下几种场景:

  1. 连续子数组或子序列问题:滑动窗口通常用来解决连续的子数组或子序列的问题,比如本题中要求连续的 k 个数字的和。
  2. 窗口大小固定:滑动窗口适用于固定窗口大小的场景,比如本题中,我们始终需要比较连续 k 个数字的和。

如果采用暴力解法,我们可以尝试遍历数组中每一个可能的长度为 k 的子数组,然后计算其和并与当前最大和进行比较。这种方法的复杂度是 O(N * k),其中 N 是数组的长度。对于每一个可能的起点,我们都需要重新计算一遍 k 个数字的和,这样在处理大量数据时会非常耗时。

2、滑动窗口如何提升效率?

滑动窗口通过复用前一次的计算结果,减少了重复计算。具体来说,滑动窗口的做法是:

  1. 计算第一个窗口的和。
  2. 之后的每一个窗口,都可以通过从当前窗口的和中减去左边的元素,并加上右边的新元素来更新,而不需要重新计算整个窗口的和。

滑动窗口算法只需要遍历数组一次,时间复杂度是 O(N),这显著提高了效率。

3、具体步骤:

这个问题属于经典的“滑动窗口”问题。我们需要找到给定数组中连续 k 个数字的最大和,滑动窗口算法非常适合这种问题。

解题思路如下:

  1. 初始化窗口:首先计算前 k 个数字的和,作为初始窗口的和。
  2. 滑动窗口遍历数组:从 k 开始,逐步向右移动窗口,每次移动时,去掉窗口最左边的元素,加入窗口最右边的元素。这样,我们就可以通过简单的加减操作更新窗口的和,而不需要重复计算整个窗口。
  3. 记录最大和:在每次滑动窗口时,比较当前窗口的和和最大和,保留较大者。
  4. 返回结果:最后输出最大和。

六、Python算法源码

# 定义主函数
def main():
    # 读取输入的数字字符串并将其分割为整数数组
    num_str = input().split(',')
    nums = list(map(int, num_str))  # 将字符串列表转换为整数列表

    # 读取咒语数字 k
    k = int(input())

    # 调用计算最大连续 k 个数的和的函数
    print(max_sum(nums, k))

# 计算最大连续 k 个宝箱数字和
def max_sum(nums, k):
    n = len(nums)  # 获取数组长度

    # 初始化第一个窗口的和
    current_sum = sum(nums[:k])  # 计算前 k 个数字的和
    max_sum = current_sum  # 将第一个窗口的和设为最大和

    # 滑动窗口,从第 k 个数字开始
    for i in range(k, n):
        current_sum = current_sum - nums[i - k] + nums[i]  # 滑动窗口,更新当前窗口的和
        max_sum = max(max_sum, current_sum)  # 更新最大和

    return max_sum  # 返回最大和

# 运行主程序
if __name__ == "__main__":
    main()

七、JavaScript算法源码

// 定义主函数
function main() {
    // 读取输入的数字字符串并分割成整数数组
    const numStr = prompt("Enter numbers:").split(',');
    const nums = numStr.map(Number);  // 将字符串数组转换为整数数组

    // 读取咒语数字 k
    const k = parseInt(prompt("Enter k:"));

    // 调用计算最大连续 k 个数的和的函数
    console.log(maxSum(nums, k));
}

// 计算最大连续 k 个宝箱数字和
function maxSum(nums, k) {
    const n = nums.length;  // 获取数组长度

    // 初始化第一个窗口的和
    let currentSum = 0;
    for (let i = 0; i < k; i++) {
        currentSum += nums[i];  // 计算第一个窗口的和
    }

    let maxSum = currentSum;  // 将第一个窗口的和设为最大和

    // 滑动窗口,从第 k 个数字开始
    for (let i = k; i < n; i++) {
        currentSum = currentSum - nums[i - k] + nums[i];  // 滑动窗口,更新当前窗口的和
        maxSum = Math.max(maxSum, currentSum);  // 更新最大和
    }

    return maxSum;  // 返回最大和
}

// 运行主程序
main();

八、C算法源码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 函数声明
int maxSum(int* nums, int k, int n);

int main() {
    char input[1000000];  // 用于存储输入字符串
    fgets(input, sizeof(input), stdin);  // 读取输入的数字字符串

    // 分割输入字符串并转换为整数数组
    char* token = strtok(input, ",");
    int nums[100000];  // 假设最多有100000个数字
    int count = 0;
    while (token != NULL) {
        nums[count++] = atoi(token);  // 将字符串转为整数并存入数组
        token = strtok(NULL, ",");
    }

    int k;
    scanf("%d", &k);  // 读取咒语数字 k

    // 调用计算最大连续 k 个数的和的函数并打印结果
    printf("%d\n", maxSum(nums, k, count));

    return 0;
}

// 计算最大连续 k 个宝箱数字和
int maxSum(int* nums, int k, int n) {
    // 初始化第一个窗口的和
    int currentSum = 0;
    for (int i = 0; i < k; i++) {
        currentSum += nums[i];  // 计算第一个窗口的和
    }

    int maxSum = currentSum;  // 将第一个窗口的和设为最大和

    // 滑动窗口,从第 k 个数字开始
    for (int i = k; i < n; i++) {
        currentSum = currentSum - nums[i - k] + nums[i];  // 滑动窗口,更新当前窗口的和
        if (currentSum > maxSum) {
            maxSum = currentSum;  // 更新最大和
        }
    }

    return maxSum;  // 返回最大和
}

九、C++算法源码

#include <iostream>
#include <vector>
#include <sstream>

using namespace std;

// 函数声明
int maxSum(vector<int>& nums, int k);

int main() {
    string input;
    getline(cin, input);  // 读取输入的数字字符串

    // 分割输入字符串并转换为整数数组
    vector<int> nums;
    stringstream ss(input);
    string temp;
    while (getline(ss, temp, ',')) {
        nums.push_back(stoi(temp));  // 将每个字符串转换为整数并存入数组
    }

    int k;
    cin >> k;  // 读取咒语数字 k

    // 调用计算最大连续 k 个数的和的函数并打印结果
    cout << maxSum(nums, k) << endl;

    return 0;
}

// 计算最大连续 k 个宝箱数字和
int maxSum(vector<int>& nums, int k) {
    int n = nums.size();  // 获取数组长度

    // 初始化第一个窗口的和
    int currentSum = 0;
    for (int i = 0; i < k; i++) {
        currentSum += nums[i];  // 计算第一个窗口的和
    }

    int maxSum = currentSum;  // 将第一个窗口的和设为最大和

    // 滑动窗口,从第 k 个数字开始
    for (int i = k; i < n; i++) {
        currentSum = currentSum - nums[i - k] + nums[i];  // 滑动窗口,更新当前窗口的和
        maxSum = max(maxSum, currentSum);  // 更新最大和
    }

    return maxSum;  // 返回最大和
}


🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)

🏆本文收录于,华为OD机试真题(Python/JS/C/C++)

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

在这里插入图片描述


http://www.kler.cn/news/308910.html

相关文章:

  • 小程序开关组件
  • ArrayList的扩容机制
  • Spring 源码解读:实现@Scope与自定义作用域
  • 前端开发第三节课
  • 解决使用阿里云DataV Geo在线地图路径访问403问题
  • 深入解析JSON:数据交换的通用语言
  • Spring Boot-国际化(I18N)问题
  • 嵌入式Linux笔试题目
  • 【JavaWeb】利用IDEA2024+tomcat10配置web6.0版本搭建JavaWeb开发项目
  • Encountered error while trying to install package.> lxml
  • es6中set和map的区别
  • C++速通LeetCode简单第17题-爬楼梯
  • PostgreSQL维护——解决索引膨胀和数据死行
  • 运维的基本概念:服务器和网络基础知识
  • 瑞星微RK芯片的Buildroot构建系统镜像
  • 【Gateway】Gateway Filter Factories
  • Visual Studio 2019/2022 IntelliCode(AI辅助IntelliSense)功能介绍
  • 【SpringBoot】调度和执行定时任务--Spring Task(超详细)
  • 数据结构 - 树与二叉树
  • [强化你的LangChain工具创建技能:从基础到进阶]
  • C语言 | Leetcode C语言题解之第413题等差数列划分
  • c语言题目猜凶手问题
  • Vue2中父子组件通信双向绑定
  • 【Java】【力扣】83.删除排序链表中的重复元素
  • TensorRT-LLM——优化大型语言模型推理以实现最大性能的综合指南
  • react18基础教程系列-- 框架基础理论知识mvc/jsx/createRoot
  • 预训练蛋白质语言模型ESM-2保姆级使用教程
  • C++设计模式(更新中)
  • 数据结构:(OJ141)环形列表
  • 李宏毅2023机器学习HW15-Few-shot Classification