leetcode刷题日记0304

1.Two Sum

0304

很简单能直接想到暴力破解,两重循环,因此复杂度为O(n2)。

也有O(n)的做法,用空间换时间,用一次循环将每个元素值与其对应索引存入哈希表,并在存之前判断,要存的这个元素值是否有对应数在之前已经存进去的,这样就为时间复杂度O(n),空间复杂度为O(n)。

2.Stock Buy 3

0305

首先想着用递归来做

1.首先考虑,基准情况:如果买过两次股票,且手里股票也卖了,终止递归return 0。

2.然后考虑,推进情况:

如果手里有股票,return max(这次卖了的收益+递归下一天且手里没股票的收益,这次不卖直接递归下一天手里没股票的收益)

如果手里没股票,return max(这次买了,递归下一天手里有股票且交易次数+1的收益,这次不买直接递归下一天且手里依旧没股票的收益)

代码如下:

class Solution_recursion{
	public:
		int maxProfit(vector&prices)
		{
			return f(prices,0,0,0);
		 }
	private:
		// i 当前第几天
		// hasStock 是否有股票在手
		// counts 已经交易次数 
		
		int f(vector prices,int i,int hasStock,int counts)
		{
			//如果已经买了两次股票,并且手里没有股票了,后面天数不考虑 
			if(i>=prices.size() || (counts>=2 && hasStock<1))
			{
				return 0;
			}
			//手里有股票还能卖 
			if(hasStock>0)
			{
				return max(prices[i]+f(prices,i+1,0,counts),f(prices,i+1,1,counts)); 
			}
			//手里没股票还能买 
			return max(-prices[i]+f(prices,i+1,1,counts+1),f(prices,i+1,0,counts));
		}
};

然后发现时间复杂度超了,这里递推公式为T(n)=2T(n-1),所以时间复杂度为O(2^n)

后面看评论发现如下思路:

记录当前为第一次买股票时拥有的收益

记录当前为第一次卖股票时拥有的收益

记录当前为第二次买股票时拥有的收益

记录当前为第二次卖股票时拥有的收益

最后第二次卖股票时的收益就是两次交易后的最大收益。

下面给个例子好参考,其实就是把当前进行各种操作的最大收益进行记录。

leetcode刷题日记0304_第1张图片

代码:

class Solution
{
	public:
		int maxProfit(vector& prices)
		{
			//hold1:该天第一次买入股票可获得最大收益 
			//Sell1: 该天第一次卖出股票可获得最大收益
			//hold2:该天第二次买入股票可获得最大收益
			//Sell2:该天第二次卖出股票可获得最大收益
			//分别对四个变量进行更新,最后secSell就是最大收益值
			
			int hold1=INT_MIN,sell1=0;
			int hold2=INT_MIN,sell2=0;
			int day=1;
			for(int p : prices)
			{
				hold1=max(hold1,-p);
				sell1=max(sell1,hold1+p);
				hold2=max(hold2,sell1-p);
				sell2=max(sell2,hold2+p);
				cout << "day" << day << " : " 
				<

时间复杂度为O(n)。

3.Find k-th smallest pair distance

0306

这道题因为差最大就是1000000,所以就直接弄个1000000大小的数组,然后双重循环减一次记录每个差出现的次数,最后就找出第k小对应的下标就是第k小个差。

代码:

class Solution_bucket {
public:
    int smallestDistancePair(vector& nums, int k) {
        int n=nums.size(),N=1000000;
        vector cnt(N,0);
        for(int i=0;i=k)return i;
				k-=cnt[i];
			}
		return 0;
    }
};

时间复杂度为O(n2),空间上就耗费多个大小是1000000个int的数组。

参考别人后发现正确应该用binary_search做,时间复杂度可以优化到O(nlogn)

代码:

class Solution_bisearch {
public:
    int smallestDistancePair(vector& nums, int k) {
        sort(nums.begin(),nums.end());
        int n=nums.size(),low=0,high=1000000;
        while(low

思想是对要求的第k小个差进行二分,由于按升序排列,看符合a[j]-a[i]<=mid时前面有几个差,多于k时说明差太大,少于k时说明差太小,然后继续二分,考虑下边界情况发现return low就是第k小个差。

 

你可能感兴趣的:(数据算法)