需要解释搜索最小大和的算法

2024-05-19

我正在解决 Codility 问题作为练习,但无法回答其中一个问题。我在互联网上找到了答案,但我不明白这个算法是如何工作的。有人可以引导我逐步完成它吗? 这是问题:

 /*
  You are given integers K, M and a non-empty zero-indexed array A consisting of N integers.
  Every element of the array is not greater than M.
    You should divide this array into K blocks of consecutive elements.
    The size of the block is any integer between 0 and N. Every element of the array should belong to some block.
    The sum of the block from X to Y equals A[X] + A[X + 1] + ... + A[Y]. The sum of empty block equals 0.
    The large sum is the maximal sum of any block.
    For example, you are given integers K = 3, M = 5 and array A such that:
      A[0] = 2
      A[1] = 1
      A[2] = 5
      A[3] = 1
      A[4] = 2
      A[5] = 2
      A[6] = 2
    The array can be divided, for example, into the following blocks:
    [2, 1, 5, 1, 2, 2, 2], [], [] with a large sum of 15;
    [2], [1, 5, 1, 2], [2, 2] with a large sum of 9;
    [2, 1, 5], [], [1, 2, 2, 2] with a large sum of 8;
    [2, 1], [5, 1], [2, 2, 2] with a large sum of 6.
    The goal is to minimize the large sum. In the above example, 6 is the minimal large sum.
    Write a function:
    class Solution { public int solution(int K, int M, int[] A); }
    that, given integers K, M and a non-empty zero-indexed array A consisting of N integers, returns the minimal large sum.
    For example, given K = 3, M = 5 and array A such that:
      A[0] = 2
      A[1] = 1
      A[2] = 5
      A[3] = 1
      A[4] = 2
      A[5] = 2
      A[6] = 2
    the function should return 6, as explained above. Assume that:
    N and K are integers within the range [1..100,000];
    M is an integer within the range [0..10,000];
    each element of array A is an integer within the range [0..M].
    Complexity:
    expected worst-case time complexity is O(N*log(N+M));
    expected worst-case space complexity is O(1), beyond input storage (not counting the storage required for input arguments).
    Elements of input arrays can be modified.
 */

这是我通过对我不理解的部分的评论找到的解决方案:

      public static int solution(int K, int M, int[] A) {
    int lower = max(A);  // why lower is max?
    int upper = sum(A);  // why upper is sum?
    while (true) {
      int mid = (lower + upper) / 2;
      int blocks = calculateBlockCount(A, mid); // don't I have specified number of blocks? What blocks do? Don't get that.
      if (blocks < K) {
        upper = mid - 1;
      } else if (blocks > K) {
        lower = mid + 1;
      } else {
        return upper;
      }
    }
  }

  private static int calculateBlockCount(int[] array, int maxSum) {
    int count = 0;
    int sum = array[0];
    for (int i = 1; i < array.length; i++) {
      if (sum + array[i] > maxSum) {
        count++;
        sum = array[i];
      } else {
        sum += array[i];
      }
    }
    return count;
  }

  // returns sum of all elements in an array
  private static int sum(int[] input) {
    int sum = 0;
    for (int n : input) {
      sum += n;
    }
    return sum;
  }

  // returns max value in an array
  private static int max(int[] input) {
    int max = -1;
    for (int n : input) {
      if (n > max) {
        max = n;
      }
    }
    return max;
  }

所以代码所做的是使用一种二分搜索的形式(二分搜索的工作原理在这里得到了很好的解释,https://www.topcoder.com/community/data-science/data-science-tutorials/binary-search/ https://www.topcoder.com/community/data-science/data-science-tutorials/binary-search/。它还使用了一个与您的问题非常相似的示例。)。您可以在其中搜索每个块需要包含的最小总和。在示例中,您需要将数组分为 3 部分

进行二分搜索时,您需要定义 2 个边界,确保可以在两者之间找到答案。这里,下边界是数组中的最大值(lower)。例如,这是 5(这是如果您将数组分为 7 个块)。上边界(upper) 是 15,它是数组中所有元素的总和(这是如果将数组分成 1 个块的话。)

现在是搜索部分:在solution()您从边界和中点开始(例如 10)。 在calculateBlockCount你数一下(count ++这样做)如果您的总和最大为 10(您的中点/或maxSum in calculateBlockCount).
对于示例 10(在 while 循环中),这是 2 个块,现在代码返回这个 (blocks) to solution。然后检查是否小于或大于K,这是您想要的块数。如果其小于K your mid点很高,因为您在块中放入了许多数组元素。如果超过K,比你的mid点太高,并且您在数组中放置的数组元素太少。 现在检查后,它会将解决方案空间减半(upper = mid-1)。 每个循环都会发生这种情况,它将解决方案空间减半,使其很快收敛。

现在你在调整的同时继续经历你的mid,直到给出您输入中的金额块K.

因此,要一步一步地进行:

Mid =10 , calculateBlockCount returns 2 blocks
solution. 2 blocks < K so upper -> mid-1 =9, mid -> 7  (lower is 5)
Mid =7 , calculateBlockCount returns 2 blocks  
solution() 2 blocks < K so upper -> mid-1 =6, mid -> 5 (lower is 5, cast to int makes it 5)
Mid =5 , calculateBlockCount returns 4 blocks
solution() 4 blocks < K so lower -> mid+1 =6, mid -> 6  (lower is 6, upper is 6
Mid =6 , calculateBlockCount returns 3 blocks
So the function returns mid =6....

希望这可以帮助,

Gl 学习编码:)

编辑。使用二分查找时,先决条件是解空间是单调函数。在这种情况下确实如此,因为当 K 增加时,总和严格减少。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

需要解释搜索最小大和的算法 的相关文章

  • 尝试获取屏幕上绘制的每个随机圆圈的 x、y 坐标

    您好 我正在制作一款游戏 该游戏将在屏幕上创建随机圆圈 随机创建的圆圈的值为红色或绿色 我的问题是 我希望不仅能够确定用户何时单击其中一个圆圈 而且还能够确定他们最终单击的圆圈 红色或绿色 下面是我的代码 我的主要问题是试图找到将要绘制的圆
  • ActiveRecord 嵌套 SELECT——我可以在没有手动 SQL 的情况下完成它吗?

    我有一张桌子 上面有 除其他外 一个名字和一个等级 我想返回所有唯一名称的集合 但对于返回的每个名称 我想选择排名最高的行 这很简单 有两个嵌套的 SELECT 语句 SELECT FROM SELECT FROM foo ORDER BY
  • JTextField 和 JTextArea

    JTextField 和 JTextArea 有什么不同 是否可以在一个班级中使用这两个班级 总之 JTextField 是单行文本字段 而 JTextArea 可以跨越多行 文档中清楚地解释了这些差异 文本区 http docs orac
  • 根据重复值对 PHP 数组进行排序

    我有一个包含重复值的数组 我想对数组进行排序 以便重复次数最多的值出现在行中的第一个 这是我的数组的示例 array 1 2 3 2 1 2 2 我想对该数组进行排序 以便它根据重复项的数量对自身进行排序 如下所示 array 2 1 3
  • Android WebView文件上传

    我正在开发一个 Android 应用程序 基本上它是一个WebView和一个进度条 Facebook 的移动网站 m facebook com 已加载到WebView 当我单击 选择文件 按钮上传图像时 没有任何反应 我已经尝试了所有的解决
  • Kafka Java Consumer 已关闭

    我刚刚开始使用卡夫卡 我面临着消费者的一个小问题 我用Java写了一个消费者 我收到此异常 IllegalStateException 此消费者已关闭 我在以下行中遇到异常 ConsumerRecords
  • 使用 JAX-WS 的 WebLogic 中没有模式导入的单个 WSDL

    如何使用 JAX WS 配置由 WebLogic 10 3 6 生成的 Web 服务 以将对象架构包含在单个 WSDL 文件声明 而不是导入声明 中 示例代码 界面 import javax ejb Local Local public i
  • java.lang.Object的hashCode具体使用的算法是什么

    中使用的算法是什么JVM实施java lang Object的隐含的hashCode 方法 OpenJDK or Oracle JDK答案中首选 它依赖于实现 并且在很大程度上 该算法是entirely取决于实施 只要它是一致的 但是 根据
  • 将现有 eclipse 项目导出到 war 文件时出现“模块名称无效”

    我正在尝试将现有 Eclipse 项目导出到 war 文件 但无论我在 WAR Export 对话框页面中输入什么 系统总是返回 模块名称无效 我不知道如何解决这个问题 谢谢您的帮助 我有同样的问题 我修复了它 请按照以下步骤操作 您可以创
  • 如何使用 swagger-codegen-plugin (maven) 生成客户端代码?

    我需要使用 swagger codegen plugin for maven 在 eclipse 中生成服务器存根代码 你能帮忙怎么做吗 以及需要什么配置 在 pom xml 中 我找到了这个答案 您只需要像下面这样更改 pom xml 即
  • 如何将文件中的行读入数组?

    我正在尝试将文件作为行数组读入 然后使用 zsh 对其进行迭代 我得到的代码在大多数情况下都有效 除非输入文件包含某些字符 例如括号 这是它的一个片段 bin zsh LIST cat path to some file txt SIZE
  • 循环中的递归算法复杂度(运行时间)

    我想了解您对如何检测以下递归算法的 T n 运行时间 的意见 Charm 是一种用于发现事务数据库中频繁闭项集的算法 频繁闭项集列表是在一组交易 tids 中多次出现的频繁项 例如面包和牛奶是经常一起购买的物品 它们是通过将索引为 i 的当
  • 根据位置计算组合

    我在解决这个问题时遇到了麻烦 创建一个函数 给定字符集 C 可以生成第 N 个组合 或者返回给定起始位置 Ns 和结束位置 Ne 以及组合的最大长度 Mx 的一系列组合 一个具体的例子 令 C A B C 我们知道不同的组合将如下所示 假设
  • java swing:向 JTree 项目添加自定义图形按钮

    我想在 JTree 中的项目右侧添加一个带有小图标的附加按钮 这可以做到吗 如果是这样 怎么办 thanks Clamp 你在这方面成功了吗 我想做同样的事情 但很难让 JButton 响应用户 设置渲染器以显示按钮的过程很顺利 但所有鼠标
  • Java String ReplaceAll 方法给出非法重复错误?

    我有一个字符串 当我尝试运行时replaceAll方法 我收到这个奇怪的错误 String str something op str str replaceAll o n it works fine str str replaceAll n
  • 在 Freemarker 模板中检查 Spring 安全角色和记录的用户名

    有谁知道 freemarker 标签来检查 freemarker 文件中的 spring 安全角色和用户名 我从网络上的几个资源中发现以下代码将打印登录的用户名 但它没有打印用户名 而是打印 登录为
  • @Embeddable 中的 @GenerateValue

    我已将实体的 id 分离到一个单独的 Embeddable 类中 该实体如下 Entity Table name users public class Users EmbeddedId private Users pk id private
  • Android Google 地图无法在当前主题中找到样式“mapViewStyle”

    添加谷歌地图视图时 我扩展了MapView 使用xml编辑器将其添加到活动中 并将我的谷歌地图api密钥手动添加到布局xml文件中 我的权限在清单文件中允许互联网 我想知道的是 在 xml 编辑器中 我收到错误 无法在当前主题中找到样式 m
  • 使用 AmazonSNSClient 发送短信时的授权

    aws 官方文档如何发送短信 http docs aws amazon com sns latest dg sms publish to phone html使用 java 中的 aws SDK 非常简单 但是 当发送如底部示例所示的消息时
  • 缓存感知树的实现

    I have a tree where every node may have 0 to N children 用例是以下查询 给定指向两个节点的指针 这些节点是否位于树的同一分支内 Examples q 2 7 gt true q 5 4

随机推荐

  • Web 服务响应包含无效的 XML 字符

    我的应用程序正在连接到 Web 服务 rpc encoded 我使用的是 Axis 1 4 当 Web 服务发送响应时 它会发送一个无效字符 然后发送一个异常 http xml apache org axis stackTrace org
  • 如何在 sh 的字符串中添加换行符?

    This STR Hello nWorld echo STR 产生作为输出 Hello nWorld 代替 Hello World 我应该怎么做才能在字符串中包含换行符 注意 这个问题不是关于echo 我知道echo e 但我正在寻找一种解
  • 在 C# 中使用 Microsoft Kinect 检测手指运动

    是否可以使用 Kinect 检测手指运动 我能够检测骨骼并进行一些鼠标移动并根据另一只手的位置执行单击 我想使用手指运动来实现 鼠标点击 是否可以使用 Microsoft Kinect sdk 或其他开源类似项目 Thanks 目前只能通过
  • 无法配置“IApplicationBuilder UseOwin”

    正如官方所说document https learn microsoft com en us aspnet core fundamentals owin 我正在尝试实施UseOwin in the Startup cs 我正在尝试使用 端口
  • 如何在iOS应用程序中捕获用户的手写签名[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 在我的应用程序中 用户将请求客户提供数字化的手写签名 我需要能够在用户在触摸屏上 书写 签名时捕获签名
  • 将嵌套字典键值转换为 pyspark 数据帧

    我有一个 Pyspark 数据框 如下所示 我想提取 dic 列中的那些嵌套字典并将它们转换为 PySpark 数据帧 像这样 请让我知道如何实现这一目标 Thanks from pyspark sql import functions a
  • H2161 重复资源[一个VCL项目可以有2个类名相同但命名空间不同的表单吗?]

    我尝试在 2 个不同的命名空间中创建具有相同类名的 2 个表单 FirstNameSpace ExampleFormName TExampleFormName SecondNameSpace ExampleFormName TExample
  • 将 XSD 文件转换为 C# 可序列化类

    我尝试遵循以下答案这个问题 https stackoverflow com questions 87621 how do i map xml to c objects 但无法让 xsd exe 愉快地获取 XSD 文件并将它们转换为类 此处
  • Oracle 中的 Json_object 返回 ORA-00907: 缺少右括号

    我正在尝试将 Oracle 表数据转换为 JSON 文件 我有三个数据库 下面的代码在一个数据库中以 JSON 文件形式提供输出 但其他两个数据库抛出ORA 00907 missing right parenthesis error 从语法
  • 执行时间为零的循环

    是否有可能有一个执行时间为零的循环 我认为即使是空循环也应该有执行时间 因为存在与之相关的开销 是的 根据假设规则编译器只有义务模拟代码的可观察行为 因此 如果您有一个没有任何可观察行为的循环 那么它可以完全优化 因此实际上执行时间为零 E
  • 将DataTable批量插入postgreSQL表中

    在 SQL 中 我们执行类似的操作来批量插入数据表 SqlBulkCopy copy new SqlBulkCopy sqlCon copy DestinationTableName strDestinationTable copy Wri
  • 没有提示指令的直连接中表的顺序是否会影响性能?

    所有基于 SQL 的 RDBMS 10 年前的版本 直接连接查询 没有提示指令 中的表顺序是否会对最佳性能和内存管理产生影响 听说最后一个join应该是最大的表 您的数据库的查询优化器如何处理这种情况 回答你的问题 是的 表的顺序在连接中有
  • Azure DevOps 的缩写是什么?

    我认为它可能是 ADO 但这会使其与遗留的 Microsoft 数据访问层 ActiveX 数据对象 或它所代表的任何内容相混淆 或者 DevOps 但这会使其与一般的 DevOps 相混淆 而且它是无论如何 也没有那么短 是否有官方缩写或
  • 我可以用 HTML5/JS 编写文件吗?

    我想知道是否有什么方法可以从 HTML5 JS 写入文件 在浏览器中 假设您的最终目标是让用户将您的文件保存在他们能找到的地方 例如右键单击链接并选择 另存为 时 这些 API 的浏览器覆盖范围还不够广泛 这可能是由于出于安全考虑 然而 无
  • 在laravel中组合两个不同的无关系数据库表查询进行分页

    我的数据库中有两个不相关的表 我需要将它们合并 以便我可以将其放在我的搜索视图中 但我不知道是否可能 这是我的代码 这news and season表不相关 但它们具有相似的列 我试图将其放入一个对象中以便于分页 是否可以 search r
  • 迭代相同的表单元素

    如果一个表单重复具有相同的标签 如何在 JavaScript 中获取它的值
  • 为什么X86中没有NAND、NOR和XNOR指令?

    它们是您可以在计算机上执行的最简单的 指令 之一 它们是我亲自实施的第一个指令 执行 NOT AND x y 会使执行时间和依赖链长度和代码大小加倍 BMI1 引入了 andnot 这是一个有意义的补充 是一个独特的操作 为什么不是这个问题
  • 从节点列表中提取边和社区

    我的数据集有超过 50k 个节点 我试图从中提取可能的边缘和社区 我确实尝试使用一些图形工具 如 gephi cytoscape socnet nodexl 等来可视化和识别边缘和社区 但节点列表对于这些工具来说太大了 因此 我正在尝试编写
  • 在 Elastic Beanstalk 中禁用自动安全组命名

    创建新环境时 Beanstalk 往往会使用随机且非常大的字符串 例如 awseb e nhmvcuvtjh stack AWSEBSecurityGroup 1R8CUK434DLPG 来污染我们的安全组命名约定 这些字符串之后无法更改
  • 需要解释搜索最小大和的算法

    我正在解决 Codility 问题作为练习 但无法回答其中一个问题 我在互联网上找到了答案 但我不明白这个算法是如何工作的 有人可以引导我逐步完成它吗 这是问题 You are given integers K M and a non em