0304
很简单能直接想到暴力破解,两重循环,因此复杂度为O(n2)。
也有O(n)的做法,用空间换时间,用一次循环将每个元素值与其对应索引存入哈希表,并在存之前判断,要存的这个元素值是否有对应数在之前已经存进去的,这样就为时间复杂度O(n),空间复杂度为O(n)。
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)
后面看评论发现如下思路:
记录当前为第一次买股票时拥有的收益
记录当前为第一次卖股票时拥有的收益
记录当前为第二次买股票时拥有的收益
记录当前为第二次卖股票时拥有的收益
最后第二次卖股票时的收益就是两次交易后的最大收益。
下面给个例子好参考,其实就是把当前进行各种操作的最大收益进行记录。
代码:
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)。
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小个差。