LeetCode 面试题 16.17. 连续数列

news/2024/11/30 14:40:08/

文章目录

  • 一、题目
  • 二、C# 题解

一、题目

  给定一个整数数组,找出总和最大的连续数列,并返回总和。

示例:

输入: [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。

进阶:

  • 如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。

  点击此处跳转题目。

二、C# 题解

  使用动态规划可以实现 O(n) 的复杂度。使用 max 记录以 j 结尾的最大连续和,其递推关系为:

m a x [ j ] = M A X { m a x [ j − 1 ] + n u m s [ j ] , n u m s [ j ] > 0 m a x [ j − 1 ] , n u m s [ j ] ≤ 0 n u m s [ j ] , m a x [ j − 1 ] < 0 max[j]= MAX\left\{ \begin{array}{l l} max[j-1]+nums[j],&nums[j]>0\\ max[j-1],&nums[j]\leq0\\ nums[j],&max[j-1]<0 \end{array} \right. max[j]=MAX max[j1]+nums[j],max[j1],nums[j],nums[j]>0nums[j]0max[j1]<0

  每次纳入 nums[j] 并考虑:

  • max < 0,则直接从 j 开始就好,即设置 max = 0。因为算上前面的序列,和只会更小。
  • max += nums[j],与 ans 比较,ans 结果取最大值。

  理论上需要开辟一个 O(n) 数组存储 max,但是由于只需要求 max 的最大值 ans,因此可以边计算边更新 ans,省去了 O(n) 的空间。

public class Solution {public int MaxSubArray(int[] nums) {int ans = nums[0], max = ans;for (var j = 1; j < nums.Length; j++) {if (max < 0) max = 0;     // 先前的序列如果 < 0,则直接抛弃,从第 j 位开始重新计数max += nums[j];           // 并入第 j 位if (max > ans) ans = max; // 更新结果}return ans;}
}
  • 时间:84 ms,击败 61.11% 使用 C# 的用户
  • 内存:38.23 MB,击败 77.78% 使用 C# 的用户

  使用分治可以实现 O(logn) 的复杂度。将数组 nums 一分为二,记为 left 和 right。则 nums 的答案 Max 可能有如下 3 中情况:

  1. 在 left 中。
  2. 在 right 中。
  3. 在 left 和 right 交界处。

  因此,需要记录区间的左端最大连续和 LMax(红色) 与右端最大连续和 RMax(黄色),其对应的更新情况如下:

  • LMax:
  • RMax:

      同时,使用 Sum(绿色)记录区间的总长度。
public class Solution {public struct Range{public int LMax; // 从左端开始的最长连续和public int RMax; // 以右端结尾的最长连续和public int Sum;  // 区间总和public int Max;  // 区间内最长连续和public Range(int l, int r, int s, int m) {LMax = l;RMax = r;Sum = s;Max = m;}public static Range operator +(Range left, Range right) {int lMax = Math.Max(left.LMax, left.Sum + right.LMax);int rMax = Math.Max(right.RMax, left.RMax + right.Sum);int sum  = left.Sum + right.Sum;int max  = Math.Max(Math.Max(left.Max, right.Max), left.RMax + right.LMax);return new Range(lMax, rMax, sum, max);}}public int MaxSubArray(int[] nums) {return Partition(nums, 0, nums.Length - 1).Max;}public Range Partition(int[] nums, int i, int j) {if (i == j) return new Range(nums[i], nums[i], nums[i], nums[i]);int mid = (i + j) >> 1;return Partition(nums, i, mid) + Partition(nums, mid + 1, j);}
}
  • 时间:76 ms,击败 94.44% 使用 C# 的用户
  • 内存:38.25 MB,击败 77.78% 使用 C# 的用户

http://www.ppmy.cn/news/1199479.html

相关文章

Netty第二部

一、EventLoop和EventLoopGroup 一个Channel可以近似的理解成一个Socket的包装&#xff0c;EventLoop管理这些Channel的 1、EventLoop EventLoop作为线程&#xff0c;具体Channel由EventLoop管理&#xff0c;在AbstractChannel类的register()方法可以体现 Override public …

pcigo图床插件的简单开发

1.前言&#xff1a; 如果想写一个图床并且投入使用&#xff0c;那么&#xff0c;接入picgo一定是一个不错的选择。picgo有着windows&#xff0c;mac&#xff0c;linux等多个客户端版本。实用且方便。 2. 开发的准备&#xff1a; 2.0. 需要安装一个node node这里我就不详细说…

STL(第八课):map

STL map是C标准库中的容器&#xff0c;它是一种关联容器&#xff0c;也就是说&#xff0c;它的元素是按照键值来存储的。STL map以键值对的形式来存储数据&#xff0c;每个键对应一个值。map中的每个元素都是一个pair对象&#xff0c;pair第一个元素为键&#xff0c;第二个元素…

解决gtihub访问不到的

解决gtihub访问不到的 小编一开始也是找不到git但是通过查询资料&#xff0c;最终也是找到了解决方式 据说git的ip地址通常会变化的&#xff0c;可以通过地址查询网站查询到git当前的ip https://sites.ipaddress.com/github.com/在输入框中github.com&#xff0c;然后搜索 在…

如何再kali中下载iwebsec靶场

这个靶场有三种搭建方法&#xff1a; 第一种是在线靶场&#xff1a;http://www.iwebsec.com:81/ 第二种是虚拟机版本的&#xff0c;直接下载到本地搭建 官网地址下载&#xff1a;http://www.iwebsec.com/ 而第三种就是利用docker搭建这个靶场&#xff0c;我这里是用kali进行…

【Head First 设计模式】-- 观察者模式

背景 客户有一个WeatherData对象&#xff0c;负责追踪温度、湿度和气压等数据。现在客户给我们提了个需求&#xff0c;让我们利用WeatherData对象取得数据&#xff0c;并更新三个布告板&#xff1a;目前状况、气象统计和天气预报。 WeatherData对象提供了4个接口&#xff1a; …

vivado 布线分析

在“ Device ”窗口中开启“ Routing Resources ” &#xff08; 布线资源 &#xff09; 即可查看具体的布线资源。 缩小时显示抽象视图。抽象视图 &#xff1a; • 精简穿过器件的布线。 • 根据穿过特定区域的布线数量显示不同粗细的线条。 类似地 &#xff0c; 布局以块…

【flask跨域问题】解决它

大概7-8年前&#xff0c;前后端还没开始分离或者刚开始分离的之前&#xff0c;跨域问题很多。 后来我就没在遇到过了&#xff0c;这次做一个小项目&#xff0c;又遇到了&#xff0c;记录下。 现在前端的脚手架都自己能解决了。 1. 跨域 是因为出于浏览器的同源策略限制。同源…