题目描写叙述:

一个无序的实数数组a[i]。要求求里面大小相邻的实数的差的最大值。比方 double a[]={1,5,4,0.2,100} 这个无序的数组,相邻的数的最大差值为100-5=95.

题目分析:这题有个简单的做法。首先就是对数组进行一个排序。然后扫面一遍数据就能够得到结果。但时间复杂度依赖于排序时间复杂度,一般为O(nlog n)。

然而一般面试官会让给出一个线性空间和线性时间复杂度的算法。这时就用到了桶排序的思想。

解题思路

解题步骤例如以下:
  1. 扫面一遍数组。找到数组中的最大max,最小min值。

  2. 将[min, max]区间平均分为n-1个区间段(每一个区间段相应一个桶bucket),每一个桶用一对有序实数对[a,b] 来表示桶内的数。
  3. 再次从头到尾扫描数组,将每一个元素加入到对应的桶bucket里面。

    注意:有的桶为空(不含不论什么数据)

  4. 然后按顺序訪问每一个(非空)的相邻的桶进行比較。

    若两个非空的相邻的桶分别为(a,b) , (c,d),那么这两个非空相邻的桶的距离为 c-b。最后选择最大的非空相邻同的距离返回就可以。

注意:
  • 上述算法是空间和时间复杂度均是O(n)
  • 我们不须要计算桶内元素的距离(如b-a)。由于数组最大间隔max-min分成n-1个桶。n个元素中一定有两个相邻元素的距离大于桶内的距离(想一想抽屉原理或者鸽巢原理),所以桶内的距离是不用算的

源码:C++

在算法的实现上,注意桶为空的标记。
此外为了方便。算法实现过程中,桶内保存的不是对应的元素,而是对应元素在数组中对应的index
#include <iostream>
#include <vector>
#include <utility>
using namespace std;
/*
*一个无序的实数数组,求它们近期邻的两个值的差
**/
double maxDiff(double a[], int n){
double max = a[0];
double min = a[0];
for (int i=1; i<n; ++i){
if (max < a[i]){
max = a[i];
}
if (min > a[i]){
min = a[i];
}
}
double bar = (max - min)/(n-1);
int pos;
//pair<first,second> : first表示桶的左边界index。second表示桶的右边界index
vector< pair<int,int> > buckets(n,make_pair(-1,-1));
//这里桶内存对应数据的下标,而不是对应的数据,方便后面的数据计算,以免有精度损失。
for (int i=0; i<n; i++){
pos = (int)((a[i] - min)/bar);
if ((buckets[pos].first == -1) && (buckets[pos].second == -1)){ //下标比較,若为double型比較注意精度问题
buckets[pos].first = buckets[pos].second = i;
}else{
if (a[buckets[pos].first] > a[i])
buckets[pos].first = i;
if (a[buckets[pos].second] < a[i])
buckets[pos].second = i;
}
}
int lastIx=0;
double max_diff = 0;
double tmp_diff = 0;
for (int i=1; i<n; ++i){ //计算桶之间的距离
if ((buckets[i].first == -1) && (buckets[i].second == -1)){
//桶为空的标志,不处理
}else{
tmp_diff = a[buckets[i].first] - a[buckets[lastIx].second];
if (tmp_diff > max_diff){
max_diff = tmp_diff;
}
lastIx = i;//lastIx指上一个非空桶的index。且第一个桶和最后一个桶肯定非空。
}
}
return max_diff;
}
int main(){
double a[]={2,4,8,16,19.0,7,7,30};
cout<<maxDiff(a,8)<<endl;
return 0;
}

备注:
这道题网上有人给出了对应的解法,但对桶为空的标记没有处理好,不能好好的work。如:http://blog.csdn.net/joanlynnlove/article/details/7706194

BAT面试题 - 找一个无序实数数组中的最大差值的更多相关文章

  1. C#编写程序,找一找一个二维数组中的鞍点

    编写程序,找一找一个二维数组中的鞍点(即该位置上的元素值在行中最大,在该列上最小.有可能数组没有鞍点).要求: 1.二维数组的大小.数组元素的值在运行时输入: 2.程序有友好的提示信息. 代码: us ...

  2. LeetCode 128 Longest Consecutive Sequence 一个无序整数数组中找到最长连续序列

    Given an unsorted array of integers, find the length of the longest consecutive elements sequence.Fo ...

  3. 128 Longest Consecutive Sequence 一个无序整数数组中找到最长连续序列

    给定一个未排序的整数数组,找出最长连续序列的长度.例如,给出 [100, 4, 200, 1, 3, 2],这个最长的连续序列是 [1, 2, 3, 4].返回所求长度: 4.要求你的算法复杂度为 O ...

  4. 624. Maximum Distance in Arrays二重数组中的最大差值距离

    [抄题]: Given m arrays, and each array is sorted in ascending order. Now you can pick up two integers ...

  5. [原]Java面试题-输入一个整型数组,找出最大值、最小值,并交换。

    [Date]2013-09-19 [Author]wintys (wintys@gmail.com) http://wintys.cnblogs.com [Content]: 1.面试题 输入一个整型 ...

  6. [LeetCode]面试题53 - I. 在排序数组中查找数字 I(二分);面试题53 - II. 0~n-1中缺失的数字(二分)

    ##面试题53 - I. 在排序数组中查找数字 I ###题目 统计一个数字在排序数组中出现的次数. 示例 1: 输入: nums = [5,7,7,8,8,10], target = 8 输出: 2 ...

  7. 《剑指offer》面试题3:二维数组中的查找

    面试题3:二维数组中的查找 面试题3:二维数组中的查找题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的个二维数组和一个整数,判 ...

  8. FCC JS基础算法题(5):Return Largest Numbers in Arrays(找出多个数组中的最大数)

    题目描述: 找出多个数组中的最大数右边大数组中包含了4个小数组,分别找到每个小数组中的最大值,然后把它们串联起来,形成一个新数组.提示:你可以用for循环来迭代数组,并通过arr[i]的方式来访问数组 ...

  9. 剑指offer——面试题4:二维数组中的查找

    // 面试题4:二维数组中的查找 // 题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按 // 照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个 // 整数 ...

随机推荐

  1. C++里的模板

     1.泛型编程 --即实现一个通用的标准容器库. 所谓通用的标准容器库,就是要做到:比方List类存放全部肯恩类型的对象这样的事:泛型编程让你编写一个全然一般化并可反复使用的算法,其效率与针对某特定数 ...

  2. zoj 2317 Nice Patterns Strike Back(矩阵乘法)

    problemId=1317">http://acm.zju.edu.cn/onlinejudge/showProblem.do? problemId=1317 给出一个n*m的矩阵( ...

  3. vim-插入格式化时间

    最近一直在搞vimrc的配置.其中有一点就是,我想要实现代码快速注释的功能.而这个功能中的一个关键点就是,我要获得系统当前的时间,然后插入到我的注释里面.我知道vimrc支持shell命令,既使用:r ...

  4. c/c++中static与extern关键字介绍

    一.C语言中的static关键字 在C语言中,static可以用来修饰局部变量,全局变量以及函数.在不同的情况下static的作用不尽相同. (1)修饰局部变量 一般情况下,对于局部变量是存放在栈区的 ...

  5. BZOJ 高精度开根 JAVA代码

    晓华所在的工作组正在编写一套高精度科学计算的软件,一些简单的部分如高精度加减法.乘除法早已写完了,现在就剩下晓华所负责的部分:实数的高精度开m次根.因为一个有理数开根之后可能得到一个无理数,所以这项工 ...

  6. spring webSocket The HTTP response from the server [200] did not permit the HTTP upgrade to WebSocket

    在springboot 1.5.9版本 WebSocketConfig配置 registry.addEndpoint("/webSocket").withSockJS();在加了. ...

  7. 小米开源文件管理器MiCodeFileExplorer-源码研究(9)-入口分析

    AndroidManifest.xml是Android应用程序最重要的配置文件. 入口文件和intent-filter <application android:icon="@draw ...

  8. XML学习总结(2)——XML简单介绍

    一.XML概念 Extensible Markup Language,翻译过来为可扩展标记语言.Xml技术是w3c组织发布的,目前推荐遵循的是W3C组织于2000发布的XML1.0规范. 二.学习XM ...

  9. Swift具体解释之三----------函数(你想知道的都在这里)

    函数(你想知道的都在这里) 注:本文为作者自己总结.过于基础的就不再赘述 ,都是亲自測试的结果.如有错误或者遗漏的地方.欢迎指正.一起学习. 1. 函数的简单定义和调用 简单的无參函数就不再赘述 , ...

  10. 取消cp命令别名

    1. 取消cp命令别名unalias cpcp -rf恢复别名alias cp='cp -i'2.关闭当前用户下的cp别名配置sed -i "s/alias cp='cp -i'/#alia ...