工业园区门户网站建设方案,百度问答下载安装,wordpress wp-json链接,做图标的网站买卖股票的最佳时机含手续费
问题描述
给定一个整数数组 prices#xff0c;其中 prices[i] 表示第 i 天的股票价格#xff1b;整数 fee 代表了交易股票的手续费用。
你可以无限次地完成交易#xff0c;但是你每笔交易都需要付手续费。如果你已经购买了一个股票#xff0c;在…买卖股票的最佳时机含手续费问题描述给定一个整数数组prices其中prices[i]表示第i天的股票价格整数fee代表了交易股票的手续费用。你可以无限次地完成交易但是你每笔交易都需要付手续费。如果你已经购买了一个股票在卖出它之前你就不能再继续购买股票了。返回获得利润的最大值。注意这里的一笔交易指买入股票然后卖出股票的整个过程。示例输入: prices [1, 3, 2, 8, 4, 9], fee 2 输出: 8 解释: 能够达到的最大利润: 在此处买入 prices[0] 1 在此处卖出 prices[3] 8 交易利润: 8 - 1 - 2 5 在此处买入 prices[4] 4 在此处卖出 prices[5] 9 交易利润: 9 - 4 - 2 3 总利润: 5 3 8 输入: prices [1,3,7,5,10,3], fee 3 输出: 6 解释: 最优策略是买入1卖出10利润: 10-1-36算法思路核心思想每一天只有两种状态持有股票hold手上持有一股股票不持有股票sold手上没有股票状态转移方程持有状态hold要么之前就持有今天继续持有hold hold要么今天买入hold sold - price[i]取最大值hold max(hold, sold - price[i])不持有状态sold要么之前就不持有今天继续不持有sold sold要么今天卖出需要支付手续费sold hold price[i] - fee取最大值sold max(sold, hold price[i] - fee)初始化第一天持有hold -prices[0]买入股票第一天不持有sold 0什么也不做结果最后一天不持有股票的状态sold因为持有股票肯定不如卖出后获得现金代码实现方法一动态规划classSolution{/** * 计算含手续费的股票交易最大利润 * * param prices 股票价格数组 * param fee 交易手续费 * return 最大利润 */publicintmaxProfit(int[]prices,intfee){if(pricesnull||prices.length1){return0;}// 初始化状态inthold-prices[0];// 持有股票的最大利润intsold0;// 不持有股票的最大利润// 从第二天开始遍历for(inti1;iprices.length;i){// 保存前一天的hold状态因为会被更新intprevHoldhold;// 更新持有状态继续持有 或 买入股票holdMath.max(hold,sold-prices[i]);// 更新不持有状态继续不持有 或 卖出股票支付手续费soldMath.max(sold,prevHoldprices[i]-fee);}// 最终状态是不持有股票returnsold;}}方法二优化classSolution{/** * 直接使用变量更新无需额外空间 */publicintmaxProfit(int[]prices,intfee){if(prices.length1){return0;}inthold-prices[0];intsold0;for(inti1;iprices.length;i){// 这里需要先计算新的sold再更新holdintnewHoldMath.max(hold,sold-prices[i]);intnewSoldMath.max(sold,holdprices[i]-fee);holdnewHold;soldnewSold;}returnsold;}}算法分析时间复杂度O(n)n是价格数组的长度只需要遍历一次空间复杂度O(1)只使用常数个额外变量算法过程1prices [1,3,7,5,10,3], fee 3过程第0天hold-1, sold0第1天hold-1, soldmax(0, -13-3)0第2天hold-1, soldmax(0, -17-3)3第3天holdmax(-1, 3-5)-1, sold3第4天hold-1, soldmax(3, -110-3)6第5天holdmax(-1, 6-3)3, sold6最终结果6测试用例publicclassTestMaxProfit{publicstaticvoidmain(String[]args){SolutionsolutionnewSolution();// 测试用例1标准示例1int[]prices1{1,3,2,8,4,9};intfee12;System.out.println(Test 1: solution.maxProfit(prices1,fee1));// 8// 测试用例2标准示例2int[]prices2{1,3,7,5,10,3};intfee23;System.out.println(Test 2: solution.maxProfit(prices2,fee2));// 6// 测试用例3单天int[]prices3{1};intfee31;System.out.println(Test 3: solution.maxProfit(prices3,fee3));// 0// 测试用例4两天无利润int[]prices4{5,4};intfee41;System.out.println(Test 4: solution.maxProfit(prices4,fee4));// 0// 测试用例5两天有利润int[]prices5{1,5};intfee52;System.out.println(Test 5: solution.maxProfit(prices5,fee5));// 2 (5-1-22)// 测试用例6手续费很高int[]prices6{1,5,10};intfee610;System.out.println(Test 6: solution.maxProfit(prices6,fee6));// 0// 测试用例7递增序列int[]prices7{1,2,3,4,5};intfee71;System.out.println(Test 7: solution.maxProfit(prices7,fee7));// 3 (5-1-13)// 测试用例8递减序列int[]prices8{5,4,3,2,1};intfee81;System.out.println(Test 8: solution.maxProfit(prices8,fee8));// 0}}关键点状态定义hold表示持有股票时的最大利润可能是负数sold表示不持有股票时的最大利润始终≥0手续费手续费在卖出时扣除初始化第一天持有股票的成本是-prices[0]第一天不持有股票的利润是0最终状态最后一天应该不持有股票因为持有股票不如卖出所以返回sold而不是max(hold, sold)常见问题为什么手续费只在卖出时扣除规定每笔交易都需要手续费一笔交易包括买入和卖出在动态规划中可以在买入或卖出时扣除效果相同选择在卖出时扣除更符合实际交易场景能否在同一天买入和卖出这样会损失手续费不会是最优解