数组精选题目三连(5)

子数组的最大累加和问题

输入一个整形数组,求数组中连续的子数组使其和最大。比如,数组x

应该返回 x[2..6]的和187.

 

这四个代码完成的功能都是求最大子数组(注意用词准确,子数组连续,子序列可以不连续)。

1)

for(i = 1; i <= n; i++)scanf("%d", &num[i]);
ans = num[1]; 
for(i = 1; i <= n; i++)
{for(j = i; j <= n; j++) {s = 0;for(k = i; k <= j; k++)s += num[k];if(s > ans)ans = s;}
}

分别枚举每一个子数组的起点和终点,也就是i和j,对于每一个起点和终点,对中间部分求和,也就是k循环。显然有n个起点n个终点(去重减半,不影响复杂度),所以子数组数量为O(N^2),对于每个子数组,我们要遍历一下求和,子数组长度1-n不等,遍历一遍平均O(N),乘起来O(N^3).(注意可能产生时间更大的错觉)。找出所有子数组中最大的即可。

2)

for(i = 1; i <= n; i++)scanf("%d", &num[i]);
sum[0] = 0;
for(i = 1; i <= n; i++) {sum[i] = num[i] + sum[i - 1];
}
ans = num[1]; 
for(i = 1; i <= n; i++) {for(j = i; j <= n; j++) {s = sum[j] - sum[i - 1];if(s > ans) ans = s;}
}

预处理出每一个以第一个元素开始,第i个元素结尾的子数组和,还是枚举每个起点终点,但是我们求和时直接减就可以了,不用遍历。对于每个子数组,操作为O(1),子数组数量O(N^2),所以总时间O(N^2).

3)

int solve(int left, int right)
{if(left == right)return num[left];mid = (left + right) / 2;lans = solve(left, mid);rans = solve(mid + 1, right);sum = 0, lmax = num[mid], rmax = num[mid + 1];for(i = mid; i >= left; i--) {sum += num[i];if(sum > lmax) lmax = sum;}sum = 0;for(i = mid + 1; i <= right; i++) {sum += num[i];if(sum > rmax) rmax = sum;}ans = lmax + rmax;if(lans > ans) ans = lans;if(rans > ans) ans = rans;return ans;
}int main(void)
{scanf("%d", &n);for(i = 1; i <= n; i++)scanf("%d", &num[i]);printf("%d\n", solve(1, n));return 0;
}

二分,求左右两边最大子数组,取最大。但是还有一种情况:包含断点的那些子数组也要考虑,请思考那两个那两个循环为什么那么写?最后逻辑为何正确?

4)动态规划入门思想

没有枚举,num[i]的含义是以下标i结尾的所有子数组中最大的。

遍历数组,对于第i个元素,它的所有子数组下标范围有[1,i],[2,i].....[i-1,i],还有它自己,我们看i-1个元素,他的子数组为[1,i-1],[2,i-1].....[i-1]。请想num[i]的含义,我们求i结尾的,只要把i-1结尾的最大加上i就好了,当然如果i-1结尾最大子数组是负的,i结尾最大子数组就是它本身。

为什么O(N)?时间省在哪里了?我们省掉了许多没必要的计算,计算i时,之前的数组和已经都计算过,朴素算法并没有记录下来,而是重复计算,造成时间浪费。算法优化的过程就是去掉重复计算的过程。
 

for(i = 1; i <= n; i++)scanf("%d", &num[i]);num[0] = 0;
ans = num[1];
for(i = 1; i <= n; i++) 
{if(num[i - 1] > 0) num[i] += num[i - 1];elsenum[i] += 0;if(num[i] > ans) ans = num[i];
}

子矩阵的最大累加和问题

给一个矩阵,请找出一个矩阵中,和最大的子矩阵。

 

 

 

如果大家看懂了之前的讲解,我给个提示:利用第二个代码和第四个代码思想的结合

 

 

解释:

1   2  3   4

-1 -2  1   2

1   3   -2  1

-1  -2  -1  -3

如图是前三行整体最大

怎么做呢?

先用第二个代码的思想,我们进行预处理

每个数代表这一列到这个数位置截止,累加和。

1  2  3  4

0  0  4  6

1  3  2  7

0  1  1  4

然后,我们枚举每一列的起点和终点分别为第0,1,2,3行

然后压缩成一维来做

比如求1-3行的这个矩形,我们拿0和3行减一下就行了

0-1,1-2,1-3,4-4=-1,-1,-2,0就是1-3行压缩后的结果

然后按一维dp来做就好
 

public class SubMatrixMaxSum {public static int maxSum(int[][] m) {if (m == null || m.length == 0 || m[0].length == 0) {return 0;}int max = Integer.MIN_VALUE;int cur = 0;int[] s = null; // 累加数组for (int i = 0; i != m.length; i++) {s = new int[m[0].length];for (int j = i; j != m.length; j++) {cur = 0;for (int k = 0; k != s.length; k++) {s[k] += m[j][k];cur += s[k];max = Math.max(max, cur);cur = cur < 0 ? 0 : cur;}}}return max;}public static void main(String[] args) {int[][] matrix = { { -90, 48, 78 }, { 64, -40, 64 }, { -81, -7, 66 } };System.out.println(maxSum(matrix));}}

子数组的最大累乘积

题目:

给定一个double类型的数组arr,其中的元素可正、可负、可为0。返回子数组累乘的最大乘积。

思路:

假设以arr[i-1]结尾的数组最小累乘积为min,最大累乘积为max,那么以arr[i]结尾的数组的最大累乘积可能有三种情况。

  • max*arr[i]//本身乘之前的最大累乘
  • min*arr[i]//可能是负负得正变成最大的
  • arr[i]//可能就是它本身,比如之前的max小于1

public class SubArrayMaxProduct {public static double maxProduct(double[] arr) {if (arr == null || arr.length == 0) {return 0;}double max = arr[0];double min = arr[0];double res = arr[0];double maxEnd = 0;double minEnd = 0;for (int i = 1; i < arr.length; ++i) {maxEnd = max * arr[i];minEnd = min * arr[i];max = Math.max(Math.max(maxEnd, minEnd), arr[i]);min = Math.min(Math.min(maxEnd, minEnd), arr[i]);res = Math.max(res, max);}return res;}public static void main(String[] args) {double[] arr = { -2.5, 4, 0, 3, 0.5, 8, -1 };System.out.println(maxProduct(arr));}}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/445384.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大数据学习(1)-大数据概述

文章目录目录大数据产生背景大数据概念大数据影响大数据应用大数据关键技术大数据产业大数据&#xff0c;云计算&#xff0c;物联网关系云计算物联网大数据&#xff0c;物联网&#xff0c;云计算三者之间联系目录 大数据产生背景 三次信息化浪潮 根据IBM前首席执行官郭士纳福…

java常用类介绍及源码阅读(LinkedList)

java.util 类 LinkedList<E> java.lang.Objectjava.util.AbstractCollection<E>java.util.AbstractList<E>java.util.AbstractSequentialList<E>java.util.LinkedList<E> List 接口的链接列表实现。实现所有可选的列表操作&#xff0c;并且允…

矩阵论-集合与映射,线性空间及其性质

线性空间与线性变换综述1.1 线性空间1.1.1 集合与映射1.1.2 线性空间及其性质综述 本系列博文主要总结学习矩阵论的心得笔记&#xff0c;参考数目《矩阵论》–张凯院&#xff1b;整个文章的整理体系参照行书过程。 1.1 线性空间 1.1.1 集合与映射 1.集合&#xff1a;将很多…

机器学习知识总结系列-机器学习中的数学-概率与数理统计(1-3-1)

文章目录目录1.概率与统计1.1 机器学习与概率统计之间的关系1.2 重要的统计量1.2.1 期望1.2.2 方差1.2.3 协方差&#xff0c;相关系数协方差相关系数1.2.4 矩1.3 重要的定理与不等式1.4 用样本估计参数目录 1.概率与统计 1.1 机器学习与概率统计之间的关系 1.什么是概率问题…

redis——事件

redis服务器是一个事件驱动程序。 需要处理两类事件&#xff1a; 1&#xff09;文件事件&#xff1a;redis是通过套接字与客户端或者其他服务器连接的&#xff0c;而文件事件就是服务器对套接字操作的抽象。 2&#xff09;时间事件&#xff1a;服务器对一些定时操作的抽象。…

自然语言处理(1)-概述

自然语言处理-概述概述1.基本概念2.人类语言技术HLT发展简史3.HLT 研究内容4.基本问题和主要困难5.基本研究方法概述 本系列文章计划总结整理中国科学院大学宗成庆老师《自然语言处理》课程相关知识&#xff0c;参考数目《统计自然语言处理》-第二版&#xff0c;宗成庆。 1.基…

redis——客户端

redis服务器是典型的一对多服务器&#xff0c;通过使用由IO多路复用技术实现的文件事件处理器&#xff0c;redis服务器使用了单线程单进程的方式来处理请求。 客户端的属性 描述符 客户端状态的 fd 属性记录了客户端正在使用的套接字描述符&#xff1a; typedef struct red…

矩阵论-线性空间的基与坐标,基变换坐标变换

线性空间与线性变换综述1.1 线性空间1.1.3 线性空间的基与坐标1.1.4 基变换与坐标变换综述 本系列博文主要总结学习矩阵论的心得笔记&#xff0c;参考数目《矩阵论》–张凯院&#xff1b;整个文章的整理体系参照行书过程。 1.1 线性空间 1.1.3 线性空间的基与坐标 向量的坐…

大数据学习(2-1)-Hadoop安装教程-单机模式和伪分布模式(Ubuntu14.04LTS)

文章目录目录1.linxu的安装1.1安装Linux虚拟机1.2安装Linux和Windows双系统2.Hadoop的安装2.1 Hadoop安装前配置2.1.1 配置Hadoop用户2.1.2 安装 ssh , 配置ssh免密登录2.1.3 安装java环境2.2 Hadoop的安装3.Hadoop单机版配置4.Hadoop伪分布版配置目录 1.linxu的安装 1.1安装…

mysql——JDBC

概述 JDBC&#xff1a;java Data Base Connectivity ,java数据库连接&#xff0c;它是一种用于执行sql语句的java API&#xff0c;为多种关系数据库提供统一访问。 其实就是一组用java编写的类和接口。 JDBC API 提供两类主要接口&#xff1a; 1&#xff09;面向开发人员的…

数组精选题目三连(6)

题目一&#xff1a;调整有序的arr数组&#xff0c;使得左半部分有序且不重复&#xff0c;不用保证右边是否有序。 思路&#xff1a; u : 左边的最后位置&#xff0c;即0---u为答案 i : 从u到右遍历 当arr[i]和arr[u]不相等时&#…

大数据学习(2-2)- 使用docker安装配置Hadoop环境

我的思路是这样&#xff1a;安装ubuntu系统---->下载docker---->在docker里拉取hadoop镜像---->在此镜像里创建三个容器(Master、Slave1、Slave2)---->完成完全分布式 1. 安装ubuntu系统(无论你是安装的单系统&#xff0c;还是用虚拟机安装了ubuntu) 如果想安装单…

自然语言处理(2)-信息论基础

自然语言处理-数学基础概述1.信息论基础1.1熵1.2 联合熵和条件熵1.3 相对熵和交叉熵1.4 互信息和双字耦合度1.5 噪声信道模型概述 本系列文章计划总结整理中国科学院大学宗成庆老师《自然语言处理》课程相关知识&#xff0c;参考数目《统计自然语言处理》-第二版&#xff0c;宗…

servlet基础总结

什么是servlet Servlet&#xff08;Server Applet&#xff09;是Java Servlet的简称&#xff0c;是小服务程序或服务连接器&#xff0c;是用Java编写的服务器端程序&#xff0c;主要功能在于交互式地浏览和修改数据&#xff0c;生成动态Web内容. 狭义的Servlet是指Java语言实…

大数据学习(3)- 分布式文件系统HDFS

文章目录目录1.分布式文件系统1.1 计算机集群概念1.2 分布式文件系统结构2.HDFS简介2.1 HDFS设计的目标2.2HDFS的局限性2.3 块的概念2.4 HDFS主要组件及其功能2.4.1 名称节点2.4.2 第二名称节点2.4.3 数据节点3.HDFS体系结构3.1 HDFS体系结构介绍3.2 HDFS体系结构的局限性4.HDF…

Python 图片转简单字符画

字符画是一系列字符的组合&#xff0c;我们可以把字符看作是比较大块的像素&#xff0c;一个字符能表现一种颜色&#xff08;暂且这么理解吧&#xff09;&#xff0c;字符的种类越多&#xff0c;可以表现的颜色也越多&#xff0c;图片也会更有层次感。 灰度值&#xff1a;指黑…

大数据学习(4)--分布式数据库HBase

文章目录目录1.HBase概述1.1BigTable1.2 HBase简介1.3 HBase和传统的关系型数据库之间的区别2.HBase访问接口3.HBase数据模型3.1 数据模型概述3.2 数据模型相关概念3.3 数据坐标3.4 概念视图3.5 物理视图3.6 面向列的存储4.HBase的实现原理4.1 HBase功能组件4.2 表和region4.3 …