首页 > 试题广场 >

买卖股票的最好时机(三)

[编程题]买卖股票的最好时机(三)
  • 热度指数:2097 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
假设你有一个数组prices,长度为n,其中prices[i]是某只股票在第i天的价格,请根据这个价格数组,返回买卖股票能获得的最大收益
1. 你最多可以对该股票有两笔交易操作,一笔交易代表着一次买入与一次卖出,但是再次购买前必须卖出之前的股票
2. 如果不能获取收益,请返回0
3. 假设买入卖出均无手续费

数据范围:,股票的价格满足
要求: 空间复杂度 ,时间复杂度
进阶:空间复杂度 ,时间复杂度

输入描述:
第一行输入一个正整数 n ,表示数组 prices 的长度
第一行输入 n 个正整数,表示数组 prices 的所有元素的值 


输出描述:
输出最大收益
示例1

输入

6
8 9 3 5 1 3

输出

4

说明

第三天(股票价格=3)买进,第四天(股票价格=5)卖出,收益为2
第五天(股票价格=1)买进,第六天(股票价格=3)卖出,收益为2
总收益为4。             
示例2

输入

4
9 8 4 1

输出

0
示例3

输入

5
1 2 8 3 8

输出

12

说明

第一笔股票交易在第一天买进,第三天卖出;第二笔股票交易在第四天买进,第五天卖出;总收益为12。
因最多只可以同时持有一只股票,所以不能在第一天进行第一笔股票交易的买进操作,又在第二天进行第二笔股票交易的买进操作(此时第一笔股票交易还没卖出),最后两笔股票交易同时在第三天卖出,也即以上操作不满足题目要求。       
public class Main {
    public static void main(String[] args) {
        Scanner scan=new Scanner(System.in);
        String str1=scan.nextLine();
        int n=Integer.valueOf(str1);
        String str2=scan.nextLine();
        String[] str3=str2.split(" ");
        int[] nums=new int[str3.length];
        for(int i=0;i<nums.length;i++){
            nums[i]=Integer.valueOf(str3[i]);
        }
        //
        if(nums.length==1){
            System.out.println(0);
            return;
        }
        int[][] dp=new int[nums.length][5];
        dp[0][0]=0;//不持有
        dp[0][1]=-nums[0];//第一次买入
        dp[0][2]=0;//第一次卖出
        dp[0][3]=-nums[0];//第二次买入
        dp[0][4]=0;//第二次卖出
        for(int i=1;i<nums.length;i++){
            dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]-nums[i]);//第一次持有
            dp[i][2]=Math.max(dp[i-1][2],dp[i-1][1]+nums[i]);
            dp[i][3]=Math.max(dp[i-1][3],dp[i-1][2]-nums[i]);
            dp[i][4]=Math.max(dp[i-1][4],dp[i-1][3]+nums[i]);
        }      
        System.out.println(Math.max(dp[nums.length-1][2],
        Math.max(dp[nums.length-1][3],dp[nums.length-1][4])));

    }
}

发表于 2023-07-11 13:18:51 回复(0)
package main

import (
    "fmt"
)

func main() {
    var n int
    fmt.Scan(&n)
    var x int
    fmt.Scan(&x)
    a,b,c,d:=-x,-x,0,0
    ans:=0
    for n>1{
        fmt.Scan(&x)
        ans=max(ans,max(max(a+x,b+x),max(c,d)))
        a,b,c,d=max(a,d-x),max(b,c-x),max(c,a+x),d
        n--
    }
    fmt.Print(ans)
}

func max(a,b int)int{
    if a>b{
        return a
    }
    return b
}

发表于 2023-02-20 16:06:37 回复(0)
O(n)空间复杂度的代码好理解,思路是两头各走一个pass,最后综合。
iO(1)就是整个过程同步进行。
#include<iostream>
using namespace std;

int main(){
  int n;
  cin>>n;
  int cost[n],forward[n],backward[n];
  for(int i=0;i<n;i++){
    cin>>cost[i];
  }
  int lowest=0x3f3f3f3f,fmost=0;
  for(int i=0;i<n;i++){
    fmost=max(fmost,cost[i]-lowest);
    forward[i]=fmost;
    lowest=min(lowest,cost[i]);
  }
  int highest=-0x3f3f3f3f,bmost=0;
  for(int i=n-1;i>=0;i--){
    bmost=max(bmost,highest-cost[i]);
    backward[i]=bmost;
    highest=max(highest,cost[i]);
  }
  int result=0;
  for(int i=0;i<n;i++){
    result=max(result,forward[i]+backward[i]);
  }
  cout<<result<<endl;
}



发表于 2022-08-31 11:54:23 回复(0)
#include<bits/stdc++.h>
using namespace std;
int maxProfit(vector<int>&prices){
    int n=prices.size();
    /*
    五种状态
    1.未进行任何操作
    2.只进行了一次买操作buy1
    3.完成了一次买卖操作sell1
    4.第二次买入buy2
    5.完成第二次买卖操作sell2
    */
    int buy1=-prices[0],sell1=0;
    int buy2=-prices[0],sell2=0;
    for(int i=1;i<n;i++){
        buy1=max(buy1,-prices[i]);
        sell1=max(sell1,buy1+prices[i]);
        buy2=max(sell1-prices[i],buy2);
        sell2=max(sell2,buy2+prices[i]);
    }
    return sell2;
}
int main(){
    int n;cin>>n;
    vector<int>prices(n);
    for(int i=0;i<n;i++)cin>>prices[i];
    cout<<maxProfit(prices);
}

发表于 2022-04-01 09:44:48 回复(0)
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int n = sc.nextInt();
            int[] arr = new int[n];
            for (int i = 0; i < n; i++) {
                arr[i] = sc.nextInt();
            }
            System.out.println(dp(n, arr));
        }
    }
    // k = 2 dp表示获得的利润!
    public static int dp(int n, int[] prices) {
        int a = 0, b = -prices[0], c = 0, d = -prices[0];
        for (int p : prices) {
            c = Math.max(c, d+p);
            d = Math.max(d, a-p);
            a = Math.max(a, b+p);
            b = Math.max(b, -p);
        }
        return c;
    }
}

发表于 2022-02-15 11:52:58 回复(0)