此题广为流传,所以不再复述题目,可以查看 LeetCode 188. 买卖股票的最佳时机 IV

写此文的目的是防止学了忘、忘了学,仅记录大概的题解思路,更加详细的思路解析可以查看(均为公众号):

此题依交易次数的不同,可以分为 一次无限次、和 k 次三种题目

以下思路、代码均根据 LeetCode 对应题目写出

一次交易

限制一次交易的情况比较简单,因为只能交易一次,所以需要寻找谷值和峰值,两者相减即最大收益

但同时也要注意时间不能倒流,需要顺序遍历数组

C# 代码

public class Solution {
    public int MaxProfit(int[] prices) {
        if(prices.Length == 0) return 0;
        int max = 0, n = prices.Length;
        int min = prices[0];
        for(int i = 1; i< n; i ++) {
            min = min > prices[i] ? prices[i] : min;
            max = prices[i] - min > max ? prices[i] - min : max;
        }

        return max;
    }
}

无限次交易

无限次交易也比较简单,遵循一个规则:股价逢涨必卖:

  • 如果股价连续几天一直上涨,那么每天都卖峰值一并卖出所获得的收益是相等的
  • 如果股价连续几天一直下跌,那么不卖,没有收益
  • 如果股价振荡,那么可以把每一天看作一次连续上涨或者连续下跌,按照前两个规则买卖

最后得出结论:逢涨必卖

C# 代码

public class Solution {
    public int MaxProfit(int[] prices) {
            if (prices.Length == 0) return 0;
            int maxProfit = 0;

            for (int i = 1; i < prices.Length; i++)
                if (prices[i] > prices[i - 1])
                    maxProfit += prices[i] - prices[i - 1];

            return maxProfit;
    }
}

k 次交易

2 次交易也可以并作 k 次交易

k 次交易事情开始变得复杂了,可以有动态规划贪心这两种理解方式,但产出的代码没有很大的差异

动态规划

动态规划的篇幅较长,可以直接参考 漫画:寻找股票买入卖出的最佳时机(整合版),递推式的推理过程非常清晰

贪心

每次交易有两种操作:买 和 卖,因此就有 2 * k 次收益的变化(建立 2 * k 大小的数组),将这些变化记录下来,每次交易操作时都获取最大值,卖出最后一笔就得到了最大收益

每过一天都模拟在当天价格下进行 k 次交易(遍历一次数据),用 Max 函数记录最大值:

  • 买入:之前的收益 – 当前股价
  • 卖出:之前的收益 + 当前股价

C# 代码

public class Solution {
    public int MaxProfit(int k, int[] prices) {
            if (prices.Length == 1 || prices.Length == 0 || k == 0) return 0;

            int recordCount = 2 * k; // k 次交易,2k 次买卖操作
            int[] profitRecord = new int[recordCount]; //收益记录数组

            for (int i = 0; i < recordCount; i += 2) //将 k 次的买入全部设为第一天股价
                profitRecord[i] = -prices[0]; //以第一天的股价买入

            for (int i = 1; i < prices.Length; i++) {
                for (int j = 0; j < recordCount ; j++) {
                    if (j == 0) profitRecord[j] = Math.Max(profitRecord[j], -prices[i]); //第一天作特殊处理
                    else if (Convert.ToBoolean(j & 1)) profitRecord[j] = Math.Max(profitRecord[j], profitRecord[j - 1] + prices[i]); //卖出操作,现收益 + 当天股价
                    else profitRecord[j] = Math.Max(profitRecord[j], profitRecord[j - 1] - prices[i]); //买入操作,现收益 - 当天股价
                }
            }

            return profitRecord[recordCount - 1]; //记录数组最后的元素
    }
}

相比 PeerTube – 自托管视频串流/直播平台,MediaCMS 没有直播功能,但是功能单一对应的是更加轻量,并且搭建方式更简单

官方 repo 已经说明了 MediaCMS 的设计初衷、使用场景等详细信息,不赘述

下文将展示如何在 Debian 10 下无域名安装并使用 MediaCMS

环境

  • Debian 10

参考

步骤

官方脚本只支持 Ubuntu 18/20,并且在默认情况下,脚本安装的 MediaCMS 无法在 IP 地址下使用,所以需要修改官方一键脚本

以下步骤在 root 用户下执行

获取 MediaCMS

mkdir /home/mediacms.io && cd /home/mediacms.io/
git clone https://github.com/mediacms-io/mediacms
cd /home/mediacms.io/mediacms/

修改安装脚本

Ubuntu 是基于 Debian 的发行版,都使用 apt 包管理,所以安装依赖的部分不用修改,但是需要删掉判断系统版本的逻辑

删除安装依赖的 if 判断,即下图的红框部分Debian 10 下 MediaCMS 的无域名搭建方式

默认情况下,脚本会请求输入 MediaCMS 的 URL,如果不输入会默认使用 localhost,之后 localhost 会被硬编码到 MediaCMS 的主程序中,这会导致进入 MediaCMS 后总是被重定向到 localhost,无法正常使用系统,所以需要更改脚本中的 localhost 为机器的 IP 地址,如下图Debian 10 下 MediaCMS 的无域名搭建方式

修改后的脚本如下图Debian 10 下 MediaCMS 的无域名搭建方式

安装 MediaCMS

在 MediaCMS 主目录运行

bash ./install.sh

脚本会安装系统依赖和 python 环境并配置 Nginx,最后启动 MediaCMS 服务

运行结束后会输出管理员密码,进入 MediaCMS 后输入此密码登录 admin 账号Debian 10 下 MediaCMS 的无域名搭建方式 Continue reading “Debian 10 下 MediaCMS 的无域名搭建方式”