动态规划算法(微软一面笔试题:股票交易,O(N)时间复杂度O(1)空间复杂度)

  1.  此问题简化为:求数组中两个元素差的最大值(后面的元素减去前面的元素)
  2. 自从暑假面试被鄙视之后,回来就经常想这个问题,到今天应该快两个月了。在这个下午,我又拿出草稿纸,总算找到了思路,把它给搞定了。就像一个心愿一样,完结了。
  3. 问题是这样的,如同题目:原题就不赘述了,化简之后的问题就是在数组中找到两个元素,计算后面的元素减去前面的元素的差。求出所有差的最大值。(你可以认为你在炒股票,买入价格和卖出价格就是你的盈利)
  4. 当时想到的方法是,如果一遍遍历这个数组,找到MAX,MIN元素,如果恰好,MAX在MIN的后面,这个问题就解决了,关键是如果这种情况不出现怎么办,我给出了递归的方法,回来自己想想发现不行,递归不靠谱,对一些测试用例来说很难有很高的效率。
  5. 潜意识告诉我,求数组中连续元素的最大和的方法对这个问题有很大的启发,那个问题在本博客中已经解决过了,而且我反复做了两遍,太好了。那个问题的解决思路是将全部元素的问题,看成是从两个元素大小的数组开始的问题。当这个包含两个元素的问题解决了,那么加一个新的元素会造成什么影响?要改变哪些值?每次都添加一个元素,每次都将这些可能的改变考虑进来,这样就能做到遍历整个数组的时候,问题就解决了。达到了最快的速度O(N)
  6. 有了上面的思路,这个问题居然更简单,其实现如下:
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的逆序迭代器。以前做过类似算法要求的遍历使用正向迭代器总感觉别扭,忽然想起了逆序迭代器。发现真的适合这种情形。

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C++程序员Carea

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值