删除两个元素将数组平均分成三部分,时间复杂度为 O(n)

2024-04-28

我遇到一个问题,让您删除数组中的两个元素以使三部分的总和相等。

  Ex:
  1 2 4 3 5 2 1
  After I drop the 4 and 5, it becomes 1, 2 | 3 | 2, 1

限制条件:

  1.Numbers are all integer > 0

  2.Drop two elements in the array, so the three splitted subarrays will have same subarray sum.

我已经通过使用两遍算法进行了尝试,如下所示

第一遍:O(n) 从左边开始计算累计和,这样我就可以轻松得到范围和。

第二遍:O(n^2) 使用嵌套循环获取子数组的开始和结束索引。然后,计算左、中、右之和。

// 1.get accumulated sum map
int[] sumMap = new int[A.length];
int sum = 0;
for(int i = 0; i < A.length; i ++) {
    sum += A[i];
    sumMap[i] = sum;
}

// 2.try each combination
for(int i = 1; i < A.length - 1; i ++) {
    for(int j = i + 1; j < A.length - 1; j ++) {
        int left = sumMap[i] - A[i];
        int mid = sumMap[j] - sumMap[i] - A[j];
        int right = sumMap[A.length - 1] - sumMap[j];

        if(left == mid && mid == right)return true;
    }
}

有没有更好的算法可以达到O(n)?

Thanks


  • Step 1:创建求和数组

  • Step 2:遵循两指针方法

      public boolean solution(int[] A) {
    
      int leftPointer = 1;
      int rightPointer = A.length - 2;
      int leftPartSum, middlePartSum, rightPartSum;
      int[] sumArray = new int[A.length];
    
      // Initializing the sum array
      sumArray[0] = A[0];
      for(int i = 1; i < A.length; i ++)
          sumArray[i] = sumArray[i-1] +  A[i];
    
      // Using two Pointer technique
      while(leftPointer < rightPointer) {
    
          leftPartSum = sumArray[leftPointer] - A[leftPointer];
          middlePartSum = sumArray[rightPointer] - sumArray[leftPointer] - A[rightPointer];
          rightPartSum = sumArray[A.length - 1] - sumArray[rightPointer];
    
          if(leftPartSum == middlePartSum && middlePartSum == rightPartSum)
              return true;
    
          if (leftPartSum < rightPartSum)
              leftPointer++;
          else if (leftPartSum > rightPartSum)
              rightPointer--;
          else{                   // Else condition denotes: leftPartSum == rightPartSum
              leftPointer++;
              rightPointer--;
          }
      }
      return false; // If no solution is found then returning false
      }
    

详细说明:

求和数组:在第一次遍历数组中,从左到右计算累加和。虽然这将花费 O(n) 时间来创建求和数组,但这将帮助您在任何给定时间以 O(1) 的时间获取 leftPartSum、middlePartSum 和 rightPartSum。

两指针方法:在双指针方法中,一个指针从开头开始,另一个指针从结尾开始。

在这种情况下,如果我们删除第一个元素或最后一个元素,那么我们就无法将数组分成 3 个相等的部分。因此,我们可以有把握地假设

int leftPointer = 1; 
int rightPointer = A.length - 2;

Note:数组包含从 0 到 n-1 的索引;

现在,我们将指针向彼此移动,每次移动时我们都会计算 leftPartSum、middlePartSum 和 rightPartSum。是否需要移动左指针或右指针取决于两个和(leftPartSum 或 rightPartSum)中哪一个较小。

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

删除两个元素将数组平均分成三部分,时间复杂度为 O(n) 的相关文章

随机推荐

  • 优化 Excel VBA 代码

    我在 Excel 中有以下 VBA 代码 其目标是在找到给定文本时删除一行 并删除其正下方的行 它需要扫描大约 70 万行 大约需要一个小时才能扫描 10 万行 有人看到有什么优化吗 Sub RemovePageHeaders Applic
  • 我该如何修复此错误:您需要在此活动中使用 Theme.AppCompat 主题(或后代)

    我搜索了所有互联网网站来修复此错误 但我无法解决 我只想创建带有两个按钮 是 和 否 的 AlertDialog 这是我的代码 import android content DialogInterface import android su
  • 使用Visual C++进行Linux开发时是否可以直接使用linux文件夹/usr/include

    我尝试使用针对 ubuntu 16 04 VM 的 Visual C for Linux Development 插件 与虚拟机的连接以及本地文件传输到远程文件夹 home user projects projectx 均成功 但是 当我尝
  • Vim 中的类和函数名称高亮显示

    在沉迷于它的模态输入之后 我最近刚刚从 Textmate 设置了我的 Vim 环境 不过 Vim 中的语法高亮似乎不太美观 我用 C 编写代码 由于函数调用和类名无法突出显示 因此代码更难以阅读 我玩了一下配色方案 但找不到任何与 类名 或
  • Android 中的位图圆形裁剪

    我有一个方形位图显示在半透明圆圈下方 用户可以触摸并拖动位图来定位它 我希望能够裁剪位图位于圆圈下方的任何部分 我怎样才能做到这一点 看一下圆角位图Drawable http developer android com reference
  • groff:我可以嵌入图像吗?

    我正在生成一些 troff 风格的文档 有没有办法将图像 jpg等 嵌入到groff文件中 取决于输出格式 如果您要创建 PostScript 文件 则可以使用 PSPIC 它使用 PS 文件本身和单个图像 例如 PSPIC image p
  • SwiftUI 按钮在出现时更改文本大小

    从 GIF 中可以看出 一旦工作表完全打开 完成 按钮文本就会变大 这不仅发生在这个视图中 而且也发生在使用系统图像而不是文本的其他视图中 有谁知道问题的解决方案还是我做错了什么 我仍然对 Swift 记忆犹新 NavigationView
  • JQuery 工具提示 VS JQuery UI 工具提示 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 在 Facebook 浏览器中更新 Service Worker

    遇到了一个问题 我们的一些用户在我们网站的 Facebook 浏览器中存在有问题的 Service Worker 问题 当 Facebook 应用程序用户访问我们在 FB 上共享的页面时 他们会在 FB 浏览器上看到我们的 您离线页面 该错
  • 仅重命名 pandas 数据框中的最后一列(考虑重复的标题)

    我需要重命名only我的数据框中的最后一列 问题是有许多同名列 这是有原因的 因此我无法在网上其他示例中使用该代码 有没有办法使用特定的东西来隔离最后一列 我尝试过做这样的事情df rename columns df columns 1 T
  • Azure Function 上的此平台不支持 System.Drawing

    我已阅读以下内容answer https stackoverflow com questions 51904125 azure function gives error system drawing is not supported on
  • 用于生成交互式图的 Java 库

    我想将我们的 SOA 服务可视化为图表 我们有商业服务和领域服务 gt domain service 1 e g business service 1 gt domain service 2 gt domain service 3 我目前使
  • 创建新的 IHttpActionResult 操作结果方法

    有什么办法可以让我使用新的IHttpActionResult接口返回一个HttpStatusCode NoContent回复消息 我目前正在使用return new HttpResponseMessage HttpStatusCode No
  • 如何返回从起始资源到指定路径深度的所有 S->P->O 三元组?

    我的目标是以图形方式表示指定资源的深度两条边内的 S gt P gt O 关系 p Person 1 我希望从查询中返回该路径长度内的所有关系 s p o在我的图形应用程序中进行进一步处理 我尝试了下面的第一个查询 它给了我第一组 s p
  • EntityFramework 6 AddOrUpdate 不适用于复合或复合主键

    这个问题是我周末的噩梦 我有一张桌子AddOrUpdate无法正常工作 它不断添加但从不更新 我想做的就是当我使用以下命令将新实体添加到表中时AddOrUpdate我想要它检查AppointmentId and CompletionCode
  • 是否有使用严格求值的 Haskell 编译器或预处理器?

    我正在寻找一个默认使用严格求值而不是惰性求值的 Haskell 编译器 我只想使用 OCaml 但 Haskell 的语法是好多了比 OCaml 的 Haskell 是纯粹的 并且具有很酷的功能 例如类型类 我真的不想经常把 s and 我
  • Unity3D 中 android 切换速度太慢

    我的游戏有 1000 多个帧 并且精灵的格式是 Crunch 因为这个项目中的精灵太多 当我想从Windows切换到Android时 我花了将近1天的时间来切换 实际上我不允许它完全切换 但切换到Windows并没有那么多 也许只有15分钟
  • ShareLinkContent .setContentTitle()、.setContentDescription()、.setImageUrl() 已弃用

    Facebook 开发者网站表示 自 2017 年 4 月 18 日起 Graph API 2 9 及更高版本不再支持以下参数 对于 2 8 及更低版本 这些参数将持续有效到 2017 年 7 月 17 日 1 一个contentTitle
  • 如何在 Linux 上使用 Python 导出

    我需要在 Python 中进行这样的导出 export MY DATA my export 我尝试过这样做 python mode coding utf 8 import os os system export MY DATA my exp
  • 删除两个元素将数组平均分成三部分,时间复杂度为 O(n)

    我遇到一个问题 让您删除数组中的两个元素以使三部分的总和相等 Ex 1 2 4 3 5 2 1 After I drop the 4 and 5 it becomes 1 2 3 2 1 限制条件 1 Numbers are all int