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

【华为OD】区块链文件转储系统

在这里插入图片描述

文章目录

  • 【华为OD】区块链文件转储系统
    • 题目描述
    • 输入描述
    • 输出描述
    • 示例
      • 示例一
      • 示例二
    • 解题思路
    • 解法一:滑动窗口法
      • Java实现
      • Python实现
      • C++实现
    • 解法二:暴力枚举法
      • Java实现
      • Python实现
      • C++实现
    • 算法分析
      • 时间复杂度
      • 空间复杂度
      • 推荐方案
    • 总结

【华为OD】区块链文件转储系统

题目描述

区块链底层存储是一个链式文件系统,由顺序的 N 个文件组成,每个文件的大小不一,依次为F1,F2,…,Fn。随着时间的推移,所占存储会越来越大,云平台考虑将区块链按文件转储到廉价的SATA 盘,只有连续的区块链文件才能转储到 SATA盘上,且转储的文件之和不能超过SATA 盘的容量。假设每块 SATA 盘容量为 M,求能转储的最大连续文件大小之和。

输入描述

第一行为 SATA 盘容量 M,1000 ≤ M ≤ 1000000
第二行为区块链文件大小序列 F1, F2, …, Fn。其中 1 ≤ n ≤ 100000,1 ≤ Fi ≤ 500

输出描述

求能转储的最大连续文件大小之和。

示例

示例一

输入:

1000
100 300 500 400 400 150 100

输出:

950

说明:
最大序列和为 950,序列为 [400, 400, 150]

示例二

输入:

1000
100 500 400 150 500 100

输出:

1000

说明:
最大序列和为 1000,序列为 [100, 500, 400]

解题思路

这是一个经典的最大连续子数组和问题的变种,需要在满足和不超过容量M的约束条件下,找到最大的连续子数组和。

我们可以使用两种方法来解决:

  1. 滑动窗口法:使用双指针维护一个滑动窗口,动态调整窗口大小
  2. 暴力枚举法:枚举所有可能的连续子数组,找到满足条件的最大和

解法一:滑动窗口法

滑动窗口是解决这类问题的最优方法,时间复杂度为O(n)。

Java实现

import java.util.*;public class Solution {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int M = scanner.nextInt();scanner.nextLine(); // 消费换行符String[] fileStr = scanner.nextLine().split(" ");int[] files = new int[fileStr.length];for (int i = 0; i < fileStr.length; i++) {files[i] = Integer.parseInt(fileStr[i]);}int maxSum = 0;int left = 0;int currentSum = 0;for (int right = 0; right < files.length; right++) {currentSum += files[right];// 如果当前和超过容量,收缩左边界while (currentSum > M && left <= right) {currentSum -= files[left];left++;}// 更新最大和maxSum = Math.max(maxSum, currentSum);}System.out.println(maxSum);}
}

Python实现

def solve():M = int(input())files = list(map(int, input().split()))max_sum = 0left = 0current_sum = 0for right in range(len(files)):current_sum += files[right]# 如果当前和超过容量,收缩左边界while current_sum > M and left <= right:current_sum -= files[left]left += 1# 更新最大和max_sum = max(max_sum, current_sum)print(max_sum)solve()

C++实现

#include <iostream>
#include <vector>
#include <sstream>
#include <algorithm>
using namespace std;int main() {int M;cin >> M;cin.ignore(); // 忽略换行符string line;getline(cin, line);istringstream iss(line);vector<int> files;int file;while (iss >> file) {files.push_back(file);}int maxSum = 0;int left = 0;int currentSum = 0;for (int right = 0; right < files.size(); right++) {currentSum += files[right];// 如果当前和超过容量,收缩左边界while (currentSum > M && left <= right) {currentSum -= files[left];left++;}// 更新最大和maxSum = max(maxSum, currentSum);}cout << maxSum << endl;return 0;
}

解法二:暴力枚举法

虽然时间复杂度较高O(n²),但思路简单直观,适合理解问题本质。

Java实现

import java.util.*;public class Solution2 {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int M = scanner.nextInt();scanner.nextLine();String[] fileStr = scanner.nextLine().split(" ");int[] files = new int[fileStr.length];for (int i = 0; i < fileStr.length; i++) {files[i] = Integer.parseInt(fileStr[i]);}int maxSum = 0;// 枚举所有可能的起始位置for (int i = 0; i < files.length; i++) {int currentSum = 0;// 从起始位置开始累加for (int j = i; j < files.length; j++) {currentSum += files[j];if (currentSum <= M) {maxSum = Math.max(maxSum, currentSum);} else {break; // 超过容量,停止扩展}}}System.out.println(maxSum);}
}

Python实现

def solve_brute_force():M = int(input())files = list(map(int, input().split()))max_sum = 0# 枚举所有可能的起始位置for i in range(len(files)):current_sum = 0# 从起始位置开始累加for j in range(i, len(files)):current_sum += files[j]if current_sum <= M:max_sum = max(max_sum, current_sum)else:break  # 超过容量,停止扩展print(max_sum)solve_brute_force()

C++实现

#include <iostream>
#include <vector>
#include <sstream>
#include <algorithm>
using namespace std;int main() {int M;cin >> M;cin.ignore();string line;getline(cin, line);istringstream iss(line);vector<int> files;int file;while (iss >> file) {files.push_back(file);}int maxSum = 0;// 枚举所有可能的起始位置for (int i = 0; i < files.size(); i++) {int currentSum = 0;// 从起始位置开始累加for (int j = i; j < files.size(); j++) {currentSum += files[j];if (currentSum <= M) {maxSum = max(maxSum, currentSum);} else {break; // 超过容量,停止扩展}}}cout << maxSum << endl;return 0;
}

算法分析

时间复杂度

  • 滑动窗口法:O(n),每个元素最多被访问两次
  • 暴力枚举法:O(n²),需要枚举所有可能的子数组

空间复杂度

  • 两种方法的空间复杂度都是O(n),主要用于存储输入数组

推荐方案

对于本题的数据规模(n ≤ 100000),强烈推荐使用滑动窗口法,因为:

  1. 时间复杂度更优,能够在规定时间内通过所有测试用例
  2. 代码简洁,逻辑清晰
  3. 是解决此类问题的标准算法

总结

区块链文件转储系统问题本质上是一个约束条件下的最大连续子数组和问题。通过滑动窗口技术,我们可以高效地解决这个问题。这种方法在处理连续子数组相关问题时非常有用,是算法面试中的常考知识点。


文章转载自:

http://jl5YQZXx.Lznqb.cn
http://kSUoD0Nk.Lznqb.cn
http://oJsZiJKc.Lznqb.cn
http://pHRIVVit.Lznqb.cn
http://39qncw3b.Lznqb.cn
http://GLmKECmT.Lznqb.cn
http://9flJSmb3.Lznqb.cn
http://2FyIbVO0.Lznqb.cn
http://t5ifGSWe.Lznqb.cn
http://RUVUbAXn.Lznqb.cn
http://zIuobMjk.Lznqb.cn
http://mcLaUras.Lznqb.cn
http://kZY2XFIF.Lznqb.cn
http://5hTGwsNH.Lznqb.cn
http://ZkI9l61h.Lznqb.cn
http://r6a8GxB2.Lznqb.cn
http://qUrCgOo9.Lznqb.cn
http://5LxBxFKm.Lznqb.cn
http://9H2ulEXd.Lznqb.cn
http://OwZxyFtl.Lznqb.cn
http://OFq5uSx1.Lznqb.cn
http://aOG9Hu24.Lznqb.cn
http://MKF4o3x5.Lznqb.cn
http://dO0MNPBe.Lznqb.cn
http://SvKmurjg.Lznqb.cn
http://cPCXRyu7.Lznqb.cn
http://RTLjMMjw.Lznqb.cn
http://NhAcP2Yd.Lznqb.cn
http://7URaM8yQ.Lznqb.cn
http://01oyTubZ.Lznqb.cn
http://www.dtcms.com/a/377469.html

相关文章:

  • sprintf不是像printf一样的打印函数吗
  • Js 图片加载完成 与 图片缓存加载的区别
  • 汽车动力电池管理系统(BMS):电动汽车的“智能大脑”
  • n8n add npm module 發生 Module ‘ioredis‘ is disallowed,getaddrinfo EAI_AGAIN
  • 性能——day3
  • 安卓学习 之 SeekBar(音视频播放进度条)
  • CRMEB标准版PHP订单列表功能详解与优化技巧
  • Linux基础知识(五)
  • [数据结构——lesson7.队列]
  • 在算法竞赛中怎样正确的分析一个程序的时间复杂度
  • ES6笔记4
  • 实现一个动态顺序表(C++)
  • 10 分钟上手 ECharts:从“能跑”到“生产级”的完整踩坑之旅
  • Decode Global新官网上线披露核心数据
  • 【Redis】Scan 命令使用教程:高效遍历海量数据
  • 深度解析:抗辐射电源芯片 ASP4644S2B 在空间环境中的单粒子效应表现
  • 多链冷换仓攻略:如何在 Solana、BSC 与 Base 隐身管理资产
  • 【博弈论和SG函数 | 那忘算10】巴什博奕 尼姆博弈及其变种 威佐夫博弈(附例题)
  • Cubemx+Fatfs(解决挂载Fatfs失败的问题)
  • UVa1063/LA3807 Marble Game
  • leetcode LCR 170.交易逆序对的总数
  • 【学习笔记】Https证书如何升级到国密
  • 期权行权期限一般多久?
  • 0基础Java学习过程记录——枚举、注解
  • 【C++】C++ 内存管理
  • C++ STL之list的使用
  • Midjourney绘画创作入门操作创作(宣传创意)
  • 【数据库约束】
  • 小白成长之路-centos7部署ceph存储
  • python学习进阶之面向对象(二)