在O(N)时间内求解 正数数组中 两个数相加的 最大值
一,问题描述
给定一个正数数组arr(即数组元素全是正数),找出该数组中,两个元素相加的最大值,其中被加数的下标大于加数的下标。由加法运算的可逆性,j >i 这个条件可以去掉。
即求出: maxValue = max{arr[j]+arr[i] and j > i}
在数组arr中没有重复的元素情况下,若被加数的下标可以等于加数的下标,则该问题变成了寻找正数数组arr中最大值的元素了。因为 max{arr[i]} + max{arr[i]} 一定比 max{arr[i]} + arr[j] 大,其中arr[j]为数组中的任意某个元素。
而《数据结构与算法分析 Java语言描述》Mark Allen Weiss著 书中第37页 2.28 题中并没有指出数组arr中的元素不通重复。
二,求解思路
有两种思路,一种是对数组中的每个元素,求出该元素与它后面元素的和,然后记录下最大的。
如,对于下标为 i 的元素,for each j belongs to [i+1, arr.length)需要求出 sum=arr[i]+arr[j] 其中,i belongs to [0,arr.length) and j >=i
这算法的时间复杂度为O(N^2)
第二种思路是,先将加数初始化为下标为0的那个元素(arr[i]=arr[0]),然后,j 往后扫描,若遇到比arr[i]大的元素,则下标 i=j。也就是说,i 总是记录比当前arr[i]更大的元素(贪心思想)。
更详细的解释,类似于这篇文章
代码如下:
//O(N). find out the max sum of two numbers in a positive array
public static int maxSum(int[] arr){
int i = 0;
int max = 0;//数组中所有的元素都是正数
int addValue;
for(int j = 1; j < arr.length; j++){
addValue = arr[i] + arr[j];
if(addValue > max)
max = addValue;
if(arr[j] - arr[i] > 0)
i = j;//记录更大的arr[i]
}
return max;
}
三,运行时间的比较
采用 这篇文章中提到的随机数生成算法 来随机生成一个数组,然后比较上面两个算法的运行时间。
机器环境如下:
OS:win7 64bit、RAM:6GB、CPU:Pentium(R)Dual-Core E5800@3.2GHz
时间比较如下:
数组大小 maxSum运行时间(O(N)) maxSum2算法2运行时间(O(N^2))
100*100 1 27
200*100 1 68
300*100 2 133
500*100 3 359
此外,按照同样的思路,也可以求解两个数相加的最小值了,哈哈。。。。
求两数相加的最小值,也同样是每次贪心,贪一个较arr[i]更小的值即可,这简直和求解两数相减的最大值一模一样!!!
代码如下:
public static int minSum(int[] arr){
int min = Integer.MAX_VALUE;
int i = 0;
int addValue;
for(int j = 1; j < arr.length; j++){
addValue = arr[j] + arr[i];
if(addValue < min)
min = addValue;
if(arr[j] - arr[i] < 0)
i = j;
}
return min;
}
再扩展一下:还可以计算三个数相加的最大值。还是同样的思路,当碰到比上一次运算中的 加数 更大的数时,则把该数替换掉原来加数中最小的那个加数。(三数相加,视为有三个加数。。。^-^)
再扩展一下,是不是感觉到这个问题和 求解最大子序列和 有点联系了? 二者都是直接跳过某些不需要“关注”的元素,并总是“贪心”出 下一个候选元素。
完整代码如下:
public class MaxSum {
//O(N). find out the max sum of two numbers in a positive array
public static int maxSum(int[] arr){
int i = 0;
int max = 0;//数组中所有的元素都是正数
int addValue;
for(int j = 1; j < arr.length; j++){
addValue = arr[i] + arr[j];
if(addValue > max)
max = addValue;
if(arr[j] - arr[i] > 0)
i = j;//记录更大的arr[i]
}
return max;
}
public static int maxSum2(int[] arr){
int max = 0;
int addValue;
for(int i = 0; i < arr.length; i++){
for(int j = i+1; j < arr.length; j++){
addValue = arr[j] + arr[i];
if(addValue > max)
max = addValue;
}
}
return max;
}
public static void main(String[] args) {
int[] arr = C2_2_8.algorithm3(100*100*10);
long start = System.currentTimeMillis();
int r = maxSum(arr);
long end = System.currentTimeMillis();
System.out.println("maxValue=" + r + " O(N)'s time:" + (end -start));
long start2 = System.currentTimeMillis();
int r2 = maxSum2(arr);
long end2 = System.currentTimeMillis();
System.out.println("maxValue=" + r2 + " O(N^2)'s time:" + (end2 - start2));
}
}
在O(N)时间内求解 正数数组中 两个数相加的 最大值的更多相关文章
- 2016网易实习生编程题:数组中两个数的和等于sum
题目 找出数组中两个数的和等于sum的这两个数 解题 这个题目做过很多次了,利用HashMap,key为 sum-A[i] value为 i 当 加入HashMap时候A[i] 已经存在map中,ge ...
- LeetCode 421. 数组中两个数的最大异或值(Maximum XOR of Two Numbers in an Array) 71
421. 数组中两个数的最大异或值 421. Maximum XOR of Two Numbers in an Array 题目描述 给定一个非空数组,数组中元素为 a0, a1, a2, - , a ...
- Java实现 LeetCode 421 数组中两个数的最大异或值
421. 数组中两个数的最大异或值 给定一个非空数组,数组中元素为 a0, a1, a2, - , an-1,其中 0 ≤ ai < 231 . 找到 ai 和aj 最大的异或 (XOR) 运算 ...
- [Swift]LeetCode421. 数组中两个数的最大异或值 | Maximum XOR of Two Numbers in an Array
Given a non-empty array of numbers, a0, a1, a2, … , an-1, where 0 ≤ ai < 231. Find the maximum re ...
- 421 Maximum XOR of Two Numbers in an Array 数组中两个数的最大异或值
给定一个非空数组,数组中元素为 a0, a1, a2, … , an-1,其中 0 ≤ ai < 231 .找到 ai 和aj 最大的异或 (XOR) 运算结果,其中0 ≤ i, j < ...
- 一个数组中两个数的和为N,找出这两个数字的下标
分析,两个数字的和为N.那么这两个数字是否是唯一的呢?输出的下标是否是第一对出现的呢? 1,我们假设这两个数字是唯一的 和是唯一的,那么其中一个数字越大,另一个数字就越小.想到大小关系,我们就想到了排 ...
- LeetCode 数组中两个数的最大异或值
题目链接:https://leetcode-cn.com/problems/maximum-xor-of-two-numbers-in-an-array/ 题目大意: 略. 分析: 字典树 + 贪心. ...
- 获取数组中多个相加等于0的一组数字 javascript
//获取数组中两个相加等于0的一对数字,比如[ [ -10, 10 ], [ -5, 5 ] ] var arr=[-5,10,1,-10,3,4,5,9] //对数组进行排序 arr.sort(fu ...
- Java泛型01--任意数组中两元素交换
package com.zl.generic; /** * 交换“任意”数组 中两个元素 */ public class GenericSwapArray { public static void m ...
随机推荐
- [转帖]IIS内虚拟站点配置信息说明
web.config配置详细说明 https://www.cnblogs.com/zhangxiaolei521/p/5600607.html 原作者总结的很详细 但是没有完全的看完 自己对IIS 的 ...
- Docker 方式运行 sonarqube
From 平台测试部同事的 ppt 感谢. 拉取镜像 docker pull postgres docker pull sonarqube 运行镜像 docker run --name db --re ...
- Oracle Gateways 方式创建dblink 连接 SQLSERVER数据库
1. 安装多次 发现在同一个机器上面总出问题,所以建议找一个没有安装oracle的机器上面进行安装gateways 2. 下载oracle gateways 并且解压缩, 下载地址详情见官网. 下载的 ...
- insertBefore(),appendChild()创建添加列表实例
定义: insertBefore() 方法在您指定的已有子节点之前插入新的子节点. 语法: 父级.insertBefore(新的子节点,指定的已有子节点) 实例: <input id=" ...
- jquery 祖先、子孫、同級
jquery向上遍歷,獲取祖先元素 parent()獲取選中元素的父 parents()獲取選中元素的所有的祖先節點,一直到文檔的根元素<html> parentUntil(“元素1”)獲 ...
- BZOJ3729Gty的游戏——阶梯博弈+巴什博弈+非旋转treap(平衡树动态维护dfs序)
题目描述 某一天gty在与他的妹子玩游戏.妹子提出一个游戏,给定一棵有根树,每个节点有一些石子,每次可以将不多于L的石子移动到父节点,询问将某个节点的子树中的石子移动到这个节点先手是否有必胜策略.gt ...
- BZOJ1834[ZJOI2010]网络扩容——最小费用最大流+最大流
题目描述 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用. 求: 1.在不扩容的情况下,1到N的最大流: 2.将1到N的最大流增加K所需的最小扩容费用 ...
- 05 Zabbix triggers--action--event
点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 05 Zabbix triggers--action--event 动作action: 在配置好监 ...
- 17 利用Zabbix完成VMare监控
点击返回:自学Zabbix之路 17 利用Zabbix完成VMare监控 最近在研究通过Zabbix监控VMware vSphere,Zabbix Documentation 3.0 从文档中我们看到 ...
- 【转】如何基于linux进程通信设计方案
前言 linux下的进程通信手段基本上是从Unix平台上的进程通信手段继承而来的.而对Unix发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在 ...