动态规划算法(微软一面笔试题:股票交易,O(N)时间复杂度O(1)空间复杂度)
2012-08-24 15:18
274 查看
此问题简化为:求数组中两个元素差的最大值(后面的元素减去前面的元素)
自从暑假面试被鄙视之后,回来就经常想这个问题,到今天应该快两个月了。在这个下午,我又拿出草稿纸,总算找到了思路,把它给搞定了。就像一个心愿一样,完结了。
问题是这样的,如同题目:原题就不赘述了,化简之后的问题就是在数组中找到两个元素,计算后面的元素减去前面的元素的差。求出所有差的最大值。(你可以认为你在炒股票,买入价格和卖出价格就是你的盈利)
当时想到的方法是,如果一遍遍历这个数组,找到MAX,MIN元素,如果恰好,MAX在MIN的后面,这个问题就解决了,关键是如果这种情况不出现怎么办,我给出了递归的方法,回来自己想想发现不行,递归不靠谱,对一些测试用例来说很难有很高的效率。
潜意识告诉我,求数组中连续元素的最大和的方法对这个问题有很大的启发,那个问题在本博客中已经解决过了,而且我反复做了两遍,太好了。那个问题的解决思路是将全部元素的问题,看成是从两个元素大小的数组开始的问题。当这个包含两个元素的问题解决了,那么加一个新的元素会造成什么影响?要改变哪些值?每次都添加一个元素,每次都将这些可能的改变考虑进来,这样就能做到遍历整个数组的时候,问题就解决了。达到了最快的速度O(N)
有了上面的思路,这个问题居然更简单,其实现如下:
其输出结果每两行作为一组,第一行为要考虑的数组的全部元素,第二行为其max_difference的结果。
陆陆续续的做了不少笔试题,也感觉收获很大,但毕竟做的不够,这个是第一个用已经掌握的技巧解决的。感觉算法强大!!
细心的读者还会发现,本文中的代码使用了vector的逆序迭代器。以前做过类似算法要求的遍历使用正向迭代器总感觉别扭,忽然想起了逆序迭代器。发现真的适合这种情形。
自从暑假面试被鄙视之后,回来就经常想这个问题,到今天应该快两个月了。在这个下午,我又拿出草稿纸,总算找到了思路,把它给搞定了。就像一个心愿一样,完结了。
问题是这样的,如同题目:原题就不赘述了,化简之后的问题就是在数组中找到两个元素,计算后面的元素减去前面的元素的差。求出所有差的最大值。(你可以认为你在炒股票,买入价格和卖出价格就是你的盈利)
当时想到的方法是,如果一遍遍历这个数组,找到MAX,MIN元素,如果恰好,MAX在MIN的后面,这个问题就解决了,关键是如果这种情况不出现怎么办,我给出了递归的方法,回来自己想想发现不行,递归不靠谱,对一些测试用例来说很难有很高的效率。
潜意识告诉我,求数组中连续元素的最大和的方法对这个问题有很大的启发,那个问题在本博客中已经解决过了,而且我反复做了两遍,太好了。那个问题的解决思路是将全部元素的问题,看成是从两个元素大小的数组开始的问题。当这个包含两个元素的问题解决了,那么加一个新的元素会造成什么影响?要改变哪些值?每次都添加一个元素,每次都将这些可能的改变考虑进来,这样就能做到遍历整个数组的时候,问题就解决了。达到了最快的速度O(N)
有了上面的思路,这个问题居然更简单,其实现如下:
int max_difference(const vector<int>& arr) { if (arr.size()>=2) { int MIN=min(arr[0],arr[1]); int MAX_DIFFERENCE=arr[1]-arr[0];//第一个被求出的差值,暂时作为最大的差值 for (vector<int>::size_type i=2;i<arr.size();i++) { if (arr[i]-MIN>MAX_DIFFERENCE) { MAX_DIFFERENCE=arr[i]-MIN; } if (arr[i]<MIN) { MIN=arr[i];//影响新的差值的关键在于已经找到的当前的最小元素是谁,只要将当前值减去这个最小元素就能更新MAX_DIFFERENCE } } return MAX_DIFFERENCE; } else { cout<<"size of arr is too small"; return 0; } } void give_result(int a[],int n) { vector<int> arr(a,a+n); print(arr.begin(),arr.end()); print(max_difference(arr)); } int main( void ) { int a0[]={7,9,10}; give_result(a0,3); int a1[]={10,9,7}; give_result(a1,3); int a[]={3,10,1,9}; give_result(a,4); int a2[]={3,9,2,10,1,8}; give_result(a2,6); return 0; }
其输出结果每两行作为一组,第一行为要考虑的数组的全部元素,第二行为其max_difference的结果。
陆陆续续的做了不少笔试题,也感觉收获很大,但毕竟做的不够,这个是第一个用已经掌握的技巧解决的。感觉算法强大!!
细心的读者还会发现,本文中的代码使用了vector的逆序迭代器。以前做过类似算法要求的遍历使用正向迭代器总感觉别扭,忽然想起了逆序迭代器。发现真的适合这种情形。
相关文章推荐
- 百度笔试:给定一个存放整数的数组,重新排列数组使得数组左边为奇数,右边为偶数。 要求:空间复杂度O(1),时间复杂度为O(n)
- 时间复杂度和空间复杂度
- 时间复杂度和空间复杂度
- 时间复杂度和空间复杂度
- 算法复杂度——时间复杂度和空间复杂度
- 时间复杂度和空间复杂度详解
- 时间复杂度和空间复杂度
- 给定一个存放整数的数组,重新排列数组使得数组左边为奇数,右边为偶数。要求:空间复杂度O(1),时间复杂度为O(n)
- 时间复杂度和空间复杂度详解
- 数据结构和算法学习02-时间复杂度和空间复杂度
- 数据挖掘算法的空间复杂度与时间复杂度分析
- 时间复杂度和空间复杂度
- 时间复杂度和空间复杂度1 – 数据结构和算法03
- 内部排序算法的稳定性,时间复杂度和空间复杂度
- 算法的复杂度包括时间复杂度和空间复杂度分别如何计算?
- 现有1,2……一直到n的无序数组,求排序算法,并且要求时间复杂度为O(n),空间复杂度为O(1),使用交换,而且只能交换两个数
- 帮你理解时间复杂度和空间复杂度
- 时间复杂度和空间复杂度
- 时间复杂度和空间复杂度的概念
- 时间复杂度和空间复杂度