第一次写博客还有点小紧张。前几天在一个比赛群里看到一道很有意思的算法题,题目如下:

给定一个数组,要求在数组里扣掉3个数后,所得到的4部分字数组的和相等,要求时间复杂度O(n)

题目本身并不难,难在要控制时间复杂度在O(n),一开始想了很多算法,时间复杂度还是控制不住,经过半天的思考,最终完成了代码(自己简单的测试了一下,思路应该是没问题,没找到OJ,测试数据也懒的想,有兴趣的朋友可以自行测试)。首先声明几点:

1.题目没有说数字的正负,现在好多算法题不够严谨,后来得知全部为正整数,思路一下就有了,但时候后来倒回来想,负数的情况应该也可以满足。

2.不知道有多少人会看到这篇文章,如果有什么问题,欢迎讨论,接受各种意见(大神无情的嘲讽都可以),重在交流。

回到正题,算法大致的思路是,首先计算出所有数字的和total,通过total可以算出每部分和的可能性,比如total为39,等分为4部分,则每一部分的和可能为1~9(保证在扣掉3个数字以后的total可以被4整除),大致划分出范围,便于之后的计算。

分别从数组的左右两边开始推进,维护left和right指针,同时对俩边各自的和进行累加,当两边和出现相等的情况时,我们认为此时存在有解的可能,需要进行下一步的判断。一开始在这里想了很多办法,一旦使用循环,复杂度必定大于O(n)。

关键的一部在于利用HashMap把本来的线性复杂度降为O(1)。下面贴一部分代码捎带讲解:

      //key为当前节点距0的距离,value为当前节点的序号HashMap<Integer, Integer> axis = new HashMap<>();int total = 0;for(int i = 0;i < len; ++i) {total += data[i];axis.put(total, i + 1);}

我们可以把整个数组抽象成一条延X方向的数轴,每个节点data[i]在数轴上对应的x坐标为data[0]~data[i]累加的和,把坐标作

为HashMap的key,对应的value是数组下标+1(稍后会看到value的作用)。

继续上面的思路,当然左右累加和相等时,我们需要进一步的计算得出是否满足四等分条件,这时通过计算可以得出第二和

第三部分对应的坐标(没错,就是HashMap),我们通过get()的返回值可以知道在假设有解的情况下,数组是否可以满足四等分。等

等,还差一步,即使我们通过计算得出,第二和第三部分可以被划分出来,我们只能扣掉3个值,二三中间是否有且仅有一个数字,

value发挥的作用时刻到了,value是每个节点的序号,可以直接判断得出结果。

以上就是所有的解题思路,蛮有意思的一道题(据说是阿里面试的时候给出的),比较符合校招的风格,题目不难,比较考验技

巧和平时对算法的练习程度,博主今年大三,很快面临实习,希望可以有个满意的结果,一起加油。最后贴上全部代码:

import java.util.HashMap;/*** Created by Administrator on 2017/3/3.*/
public class Divide {public static void main(String[] args) {
//        int[] data = {1, 8, 5, 2, 7, 9, 3, 6, 12, 2, 2, 5};
//        int[] data = {1, 8, 5, 2, 1, 3, 3, 2, 12, 2, 2, 5};int[] data = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};System.out.println(divide(data));}public static boolean divide(int[] data) {int len = data.length;//key为当前节点距0的距离,value为当前节点的序号HashMap<Integer, Integer> axis = new HashMap<>();int total = 0;for(int i = 0;i < len; ++i) {total += data[i];axis.put(total, i + 1);}int max = 0;for(int i = total;i > 0; --i) {if(i % 4 == 0) {max = i / 4;break;}}System.out.println(total + " " + max);int left = 1;//左边开始累加int addL = data[0];int right = len - 2;//右边开始累加int addR = data[len - 1];while(left < right) {System.out.println(addL + " " + addR);if(addL == addR && addL <= max) {int low = 2 * addL + data[left];int high = total - (2 * addR + data[right]);System.err.println(low + " " + high);if(axis.get(low) != null && axis.get(high) != null && axis.get(low) + 1 == axis.get(high)) {return true;}}if(addL < addR) {addL += data[left];++left;}else {addR += data[right];--right;}}return false;}
}

晚安。

如何用O(n)实现四等分数组相关推荐

  1. 如何用简单的方式将数组转成json

    在工作中,我们时常会遇到需要将数组形式的[{id:1,name:'ming'},{id:2,name:'daming'}]转换成 {1: {id:1,name:'ming'}, 2: {id:2,na ...

  2. 如何用指针的方法打印数组的元素

    首先要创建一个数组,对其进行初始化 int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 初始化后,我们要先求元素个数 int sz = sizeof(ar ...

  3. c语言如何用指针操作一维字符数组,C语言中数组和指针的互操作

    C是一种怀旧的语言,因为它的历史很久远,然而自从各种面向对象的编程语言的相续出现让它的影响力日减.当然了,这是无可非议的,但是C的高效性是其他语言无妨比拟的,所以我们有必要把握其中的精华与奥妙,也就有 ...

  4. python中if语句求最大值_如何用if语句向量化numpy数组中的最大值?

    我的设置:Python 2.7.4.1.numpymkl 1.7.1.windows7x64.WinPython 上下文: 我尝试实现序列最小优化算法来求解支持向量机.我使用最大违反对方法.在 问题是 ...

  5. 怎么把python结果全部显示-python 显示数组全部元素的方法

    怎么将python中的数组全部打印出来array 在python中打印array数组的方法如下: 最近小编总是在想,能陪自己到最后的,是什么样的人,昨晚玩手机到很晚,现在想突然想通了,让小编觉得,真正 ...

  6. 返回一个二维整数数组中最大子数组的和(二人结对)

    题目:返回一个二维整数数组中最大子数组的和 要求:1.输入一个二维整型数组,数组里有正数也有负数. 2.二维数组中连续的一个子矩阵组成一个子数组,每个子数组都有一个和. 3.求所有子数组的和的最大值. ...

  7. python二维数组的行和列_python 定义N行2列二维数组与赋值

    python中怎么用花括号定义一个5行4列的数组花括号是字典,不是数组. python:定义函数,输入一个m维数组X和一个整数n,输# Python3.6import numpy as npwhile ...

  8. matlab 矩阵除以一个矩阵,matlab 如何用一个数除以一个矩阵

    如何用MATLAB求一个矩阵的特征值 a=816357492>>eig(a)ans=15.00004.8990-4.8990 如何用matlab定义一个列向量 a=[7;15*ones(8 ...

  9. matlab数组求一阶导数,用matlab求符号函数数组或函数矩阵的导数实例教程

    用matlab求符号函数数组或函数矩阵的导数实例教程 在符号矩阵中,矩阵的每个元素都可以存放符号函数,这是对符号函数数组的求到运算是对数组元素逐个进行的.接下来就以实例向大家介绍一下用matlab对符 ...

最新文章

  1. 3月最新!ESI世界大学排名:371所内地高校上榜!
  2. CALayer 知识:创建带阴影效果的圆角图片图层和创建自定义绘画内容图层
  3. python同步锁和互斥锁的区别_Python实现的多线程同步与互斥锁功能示例
  4. require(),include(),require_once()和include_once()区别
  5. 华南理工计算机接口技术随堂练习_研究生考试计算机408跟845有什么区别?
  6. [spring-framework]Spring定时器的配置和使用
  7. 【牛客 - 317G】小a的排列(模拟,构造)
  8. 项目经理有必要学python吗_项目经理到底要不要懂技术
  9. 网红奶茶雪糕高价背后,到底是真好吃还是智商税
  10. [android] init进程 .rc文件中service、action的parsing
  11. wsdl 架构验证警告:来自命名空间_Let it go: DARTS 神经网络可微架构搜索 笔记
  12. [网络安全自学篇] 九.社会工程学之基础概念、IP获取、IP物理定位、文件属性
  13. js判断数组key是否存在
  14. 基于神经网络的房价预测,房价预测 神经网络
  15. ttk progress bar的显示
  16. xxxx-xx-xx系统应用(周)巡检报告模版
  17. houdini中使用vex旋转对象法线方向方法
  18. 一种使用随机抽样梯度下降算法来预估词汇量的方法
  19. Surface电池寿命延长
  20. vim:修改vim录制的宏

热门文章

  1. 若依前后端分离框架学习-3:获取菜单
  2. iOS-Undefined symbols for architecture x86_64-- 调适萤石摄像头驱动程序--萤石开放平台
  3. C#计算数组的算术平均数、几何平均数、调和平均数、平方平均数和中位数
  4. Michael Guo的技术博客
  5. PHP $_POST,$_REQUEST获取不到参数原因
  6. 超市库存管理系统java_java实现超市库存管理系统
  7. C++打卡20-【排序模板】快速排序
  8. 虹科分享|用于 VMware 的 ATTO vConfigTool™ 插件
  9. 宝塔面板一键优化补丁
  10. 城市园林类毕业论文文献包含哪些?