每日一道算法题:求数对之差的最大值
2014-11-10 21:19
489 查看
这道题目是上个月应聘某公司时在collabedit网站上进行在线笔试的第三题,题目如下:
在数组中,数字减去他右边的数字得到一个数对之差。
求所有数对之差的最大值。例如在数组{2,4,1,16,7,5,11,9}中,数对之差的最大值为11,是16减去5的结果。
解题思路:一开始想到的解法是求出数组中的每一个数字与它右边的每个数字的差值,再通过比较求出所有差值的最大值,但是这种思路的时间复杂度为O(n*n), 因为针对数组中的每个数字还需要遍历数组一次。
思路一:从左到右寻找最大数对之差可能时间复杂度偏高,那么从右到左寻找呢?抱着试试的心态,尝试着从右到左寻找最小值以及所有差值的最大值。利用了动态规划的思想。
遍历数组:
(1)记录最小值:arr[i] < min; min = arr[i];
(2)记录所有差值的最大值:arr[i] > min; diff = arr[i] - min; max_diff = max(max_diff, diff);
具体c++代码如下:
针对思路一,还可以从左到右遍历数组,求出数组的最大值和所有数对之差的最大值,进行比较便可以求出原始数组数对之差的最大值了,代码可以参照思路一的代码。
思路二:通过分而治之的思路缩小问题的规模来求解,将原始数组分为左右两个子数组,分别求出两个子数组的数对之差的最大值,这样,原始数组的数对之差的最大值就可能出现于:
(1)左边的子数组中;
(2)右边的子数组中;
(3)左边的子数组中的最大值与右边子数组的差值即为原始数组的数对之差的最大值。
具体c++代码如下:
在数组中,数字减去他右边的数字得到一个数对之差。
求所有数对之差的最大值。例如在数组{2,4,1,16,7,5,11,9}中,数对之差的最大值为11,是16减去5的结果。
解题思路:一开始想到的解法是求出数组中的每一个数字与它右边的每个数字的差值,再通过比较求出所有差值的最大值,但是这种思路的时间复杂度为O(n*n), 因为针对数组中的每个数字还需要遍历数组一次。
思路一:从左到右寻找最大数对之差可能时间复杂度偏高,那么从右到左寻找呢?抱着试试的心态,尝试着从右到左寻找最小值以及所有差值的最大值。利用了动态规划的思想。
遍历数组:
(1)记录最小值:arr[i] < min; min = arr[i];
(2)记录所有差值的最大值:arr[i] > min; diff = arr[i] - min; max_diff = max(max_diff, diff);
具体c++代码如下:
#include <iostream> using namespace std; #define MAX(a, b) ((a) > (b)?(a):(b)) #define MIN(a, b) ((a) < (b)?(a):(b)) int get_Max_Diff(int *arr, int len){ if (arr == NULL || len == 0){ return 0; } int min = MIN(arr[len - 1], arr[len - 2]); int maxdiff = arr[len - 2] - arr[len - 1]; for (int i = len - 3; i >= 0; --i){ if (arr[i] < min){ min = arr[i]; } else{ maxdiff = MAX(maxdiff, arr[i] - min); } } return maxdiff; } int main(){ int arr[] = {2, 4, 1, 16, 7, 5, 11, 9}; int result = get_Max_Diff(arr, sizeof(arr)/sizeof(int)); cout << "max_diff = " << result << endl; system("pause"); return 0; }
针对思路一,还可以从左到右遍历数组,求出数组的最大值和所有数对之差的最大值,进行比较便可以求出原始数组数对之差的最大值了,代码可以参照思路一的代码。
思路二:通过分而治之的思路缩小问题的规模来求解,将原始数组分为左右两个子数组,分别求出两个子数组的数对之差的最大值,这样,原始数组的数对之差的最大值就可能出现于:
(1)左边的子数组中;
(2)右边的子数组中;
(3)左边的子数组中的最大值与右边子数组的差值即为原始数组的数对之差的最大值。
具体c++代码如下:
#include <iostream> using namespace std; int maxdiff; void get_Max_Diff(int *arr, int len, int *max, int *min){ if (arr == NULL || len == 0){ return ; } if (len == 1){ *max = *min = arr[0]; return ; } int mid = len / 2; int max_of_left, max_of_right, min_of_left, min_of_right; get_Max_Diff(arr, mid, &max_of_left, &min_of_left); get_Max_Diff(arr + mid, len - mid, &max_of_right, &min_of_right); if (maxdiff < (max_of_left - min_of_right)){ maxdiff = max_of_left - min_of_right; } *max = (max_of_left > max_of_right) ? max_of_left:max_of_right; *min = (min_of_left < min_of_right) ? min_of_left:min_of_right; return ; } int main(){ maxdiff = 0; int arr[] = {2, 4, 1, 16, 7, 5, 11, 9}; int len = sizeof(arr) / sizeof(int); int max; int min; get_Max_Diff(arr, len, &max, &min); cout << "max_diff = " << maxdiff << endl; system("pause"); return 0; }
相关文章推荐
- 每日一道算法题:一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
- 每日一道算法题3——得到数组子数组最大和
- 生成窗口最大数值(每日一道算法题)
- 每日一道算法题:求N个整数的最大公约数
- 每日一道算法题7—— 查找最大(小)的k个元素
- 每日一道算法题:求一个矩阵中最大的二维矩阵(元素和最大)
- 每日一道算法题(1)
- 每日一道算法题(2)
- <每日一题>算法导论:最大股票收益
- 每日一道算法题——3个数字相加等于0
- 每日一道算法题(2)
- 每日一道算法题(5)
- 每日一道算法题——1
- 每天一道算法题(15)——打印1到最大的n位数
- 每日一道算法题-寻找丑数
- 删除链表的倒数第K个节点(每日一道算法题)
- 每日一道算法题2——定义一个栈,提供一个返回栈里最小元素方法
- 每日一道算法题:编程实现两个数的除法,当然不能用除法操作符
- 每天一道算法题(15)——打印1到最大的n位数
- 每日一道算法题:打印一维数组的所有组合