递归

  • 首先描述出问题

    第day天,持有or非持有的状态,已经交易times的情况下能获利多少

    1. function maxProfit(prices: number[]): number {
    2. const cache: number[][][] = new Array(prices.length).fill(0).map(() => [
    3. [-1, -1],
    4. [-1, -1],
    5. ]);
    6. function backtrack(day: number, status: number, times: number): number {
    7. // base case
    8. if (day >= prices.length || times >= 2) {
    9. return 0;
    10. }
    11. if (cache[day][status][times] !== -1) {
    12. return cache[day][status][times];
    13. }
    14. if (status === 0) {
    15. // make progress 到哪里去, 去哪儿
    16. // status 未持有
    17. cache[day][status][times] = Math.max(
    18. -prices[day] + backtrack(day + 1, (status + 1) % 2, times),
    19. backtrack(day + 1, status, times)
    20. );
    21. } else {
    22. // 持有
    23. cache[day][status][times] = Math.max(
    24. prices[day] + backtrack(day + 1, (status + 1) % 2, times + 1),
    25. backtrack(day + 1, status, times)
    26. );
    27. }
    28. return cache[day][status][times];
    29. }
    30. return backtrack(0, 0, 0);
    31. }

    动态规划

    1. function maxProfit(prices: number[]): number {
    2. const dp: number[][][] = new Array(prices.length).fill(0).map(() => [
    3. [0, 0, 0],
    4. [0, 0, 0],
    5. ]);
    6. let n = prices.length - 1;
    7. // base case
    8. dp[0][0][0] = 0;
    9. dp[0][0][1] = Number.NEGATIVE_INFINITY;
    10. dp[0][0][2] = Number.NEGATIVE_INFINITY;
    11. dp[0][1][0] = -prices[0];
    12. dp[0][1][1] = Number.NEGATIVE_INFINITY;
    13. dp[0][1][2] = Number.NEGATIVE_INFINITY;
    14. // make progress
    15. for (let i = 1; i < prices.length; i++) {
    16. // 未持有状态 从哪里来
    17. {
    18. dp[i][0][0] = 0;
    19. dp[i][0][1] = Math.max(
    20. dp[i - 1][1][0] + prices[i],
    21. dp[i - 1][0][1]
    22. );
    23. dp[i][0][2] = Math.max(
    24. dp[i - 1][1][1] + prices[i],
    25. dp[i - 1][0][2]
    26. );
    27. }
    28. // 持有状态 从哪里来 前面买入或者当前买入
    29. {
    30. dp[i][1][0] = Math.max(
    31. dp[i - 1][0][0] - prices[i],
    32. dp[i - 1][1][0]
    33. );
    34. dp[i][1][1] = Math.max(
    35. dp[i - 1][0][1] - prices[i],
    36. dp[i - 1][1][1]
    37. );
    38. // 已经交易两次还持有,所以不可能
    39. dp[i][1][2] = Number.NEGATIVE_INFINITY;
    40. }
    41. }
    42. console.table(dp);
    43. return Math.max(...dp[n][0]);
    44. }