Bsst Time to Buy and Sell Stock系列

1: leetcode第121题 Best Time to Buy and Sell Stock

题目描述:

Say you have an array for which the ith element is the price of a given stock on day i.

If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.

题意是给定一个数组,数组中每个元素代表股票的价格(第i个元素代表第i天价格)。
要求:仅仅允许一轮交易(买一次、卖一次),设计一个算法,求得最大利润。

题意分析:

法1: 贪心法,分别找到价格最低和价格最高的一天,低进高出,注意,要求最低的一天要在最高的一天之前。
所以,设定一个变量,存储在今天之前的最低价格。一定要在今天之前。
法2:把原始的序列变成差分序列,最终,用最大m子段和求解,m为1.

代码:

// 法1:分别找到价格最低和价格最高的一天,低进高出。
public class Solution121 {
    public static int maxProfit(int[] prices) {
        if (null == prices || prices.length < 2) {
            return 0;
        }

        final int n = prices.length; 
        int minPrice = prices[0]; // 记录在此之前的最低价格, 非常重要
        int maxProfit = 0;        // 记录到目前为止地 最大利润
        for (int i = 1; i != n; ++i) {
            int todayProfit = prices[i] - minPrice; // 如果今天卖出股票,能获得的最大利润是多少
            // 实时更新当前利润: 如果今天卖出股票,所取得的利润比之前卖出能获得更高利润,则今日卖出
            maxProfit = maxProfit > todayProfit ? maxProfit : todayProfit;

            // 实时更新当前最低买入价格
            minPrice = minPrice < prices[i] ? minPrice : prices[i]; 
        }

        return maxProfit;
    }
}

2: leetcode第122题 Best Time to Buy and Sell Stock II

题目描述:

Say you have an array for which the ith element is the price of a given stock on day i.

Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times). However, you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

题意是给定一个数组,数组中每个元素代表股票的价格(第i个元素代表第i天价格)。
可以买卖任意多的次数,设计一个算法,求得最大利润。

思路分析:

只要今天的股票价格比昨天高,就可以卖出。一天之内,可以先将股票卖出,然后再买回来。
则:贪心法,低进高出,把所有的正的差价都加起来。

public class Solution122 {
    public int maxProfit(int[] prices) {
        if (null == prices || 0 == prices.length) {
            return 0;
        }

        final int n = prices.length;
        int maxProfit = 0;
        for (int i = 1; i < n; ++i) {
            // 只要当天价格比前一天高,就做一次交易,同一天可以多次交易
            maxProfit += (prices[i] - prices[i - 1]) > 0 ? (prices[i] - prices[i - 1]) : 0;
        }

        return maxProfit;
    }
}

3:leetcode第123题 Best Time to Buy and Sell Stock III

题目描述:

Say you have an array for which the ith element is the price of a given stock on day i.

Design an algorithm to find the maximum profit. You may complete at most two transactions.

题目意思是给定一个数组,数组中的元素表示股票的价格(第i个数组表示第i天股票的价格)。现在要求你设计一个算法,这批股票,最多可以买卖两次,求最大的利润。

Note:

You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

即要求在买新股票之前,必须卖掉旧的股票。

思路分析:

设状态f(i), 表示区间[0, i] (0 <= i <= n - 1)的最大利润;状态g(i),表示区间[i, n - 1] (0 <= i <= n - 1)的最大利润,则最终答案为max{f(i) + g(i)} (0 <= i <= n - 1)。

即在区间[0, i]可以买卖一轮股票,在[i, n - 1]也可以买卖一轮股票。(当然也可以任意一轮都买或不买)。两个区间最大之和。

注意,两个区间都包括了i,因为在某一天,可以先卖掉,然后再买入。

代码:

public class Solution123 {
    public int maxProfit(int[] prices) {
        if (null == prices || prices.length < 2) {
            return 0;
        }

        final int n = prices.length;

        // 区间[0, i]内的最大利润,所以要从前向后遍历
        int[] f = new int[n]; // 前半段的利润,f[i]记录第i天能取得的最大利润。(默认初始化为0)
        int minPrice = prices[0]; // 前半段从前往后遍历,所以记录今天之前的最低价格
        for (int i = 1; i < n; ++i) {
            int todayProfit = prices[i] - minPrice;
            f[i] = f[i - 1] > todayProfit ? f[i - 1] : todayProfit;
            minPrice = minPrice < prices[i] ? minPrice : prices[i];
        }

        // 区间[i, n - 1]的最大利润,即今天(第i天)是买入股票,后面卖的,所以要从后向前遍历。
        int[] g = new int[n]; // 后半段的利润,g[i]记录第i天所能取得的最大利润(默认初始化为0)
        int maxPrice = prices[n - 1]; // 记录今天之后的最大价格,以用来减去今日价格
        for (int i = n - 2; i >= 0; --i) {
            int todayProfit = maxPrice - prices[i];
            g[i] = g[i + 1] > todayProfit ? g[i + 1] : todayProfit;
            maxPrice = maxPrice > prices[i] ? maxPrice : prices[i];
        }

        int maxProfit = 0;
        for (int i = 0; i < n; ++i) {
            maxProfit = maxProfit > (f[i] + g[i]) ? maxProfit : (f[i] + g[i]);
        }

        return maxProfit;
    }

}

题目4: leetcode188 Best Time to Buy and Sell Stock IV

题目描述:

Say you have an array for which the ith element is the price of a given stock on day i.

Design an algorithm to find the maximum profit. You may complete at most k transactions.

Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

给定一个数组,数组中的每个元素,代表当天股票的价格。设计一个算法,求买卖股票的最大利润。要求最多允许买卖k次。

注意: 买入股票之前,必须先将手里有的卖出去。

思路分析:

k >= n

如果k比天数n还大,那么直接求出差分数列,将所有非负数加起来就是最大利润。

k小于n。

设置两个变量global[n][k + 1]local[n][k + b1].

首先global[i][j]的表示前i天进行了j次交易(卖出j次),所取得的最大利润。即是不断地和已经计算出的local进行比较,把大的保存在global中。

然后看local,关键是要理解local的定义,local[i][j]表示,前i天进行了j次交易(卖出),并且第i天进行了第j次交易的最大利润,所以local[i][j]中必然有一次交易,也就是当近一次交易,发生在第i天。

表达式:

local[i][j]=max(global[i-1][j-1]+max(diff,0),local[i-1][j]+diff),其中diff为price[i] - price[i - 1]即今日和昨日差价。

global[i-1][j-1]+max(diff,0)为前i-1天进行j-1次交易,然后加上今天的交易(如果今天是赚钱的话那么前一天买今天买,这样就赚钱了。如果前一天买今天卖不赚钱,那么就今天买今天卖,这样就赚了0元。)

local[i-1][j]+diff则是取local第i-1天j次交易(在第i-1天卖出了股票),然后加上今天的差值(这里因为local[i-1][j]包含第i-1天卖出的交易,所以现在变成第i天卖出(即原本前i-1天交易j次,现在变成了前变成第i天卖出,注意不能变成local[i - 1][j - 1] + diff),并不会增加交易次数,而且这里无论diff是不是大于0都一定要加上,因为否则就不满足local[i][j]必须在最后一天卖出的条件了)。

global[i][j]=max(local[i][j],global[i-1][j])
local[i][j]表示前i-1天交易了j-1次,第j天交易了一次; global[i - 1][j]表示前i-1天交易了j次,第i天没有进行交易。

代码

    public int maxProfit(int k, int[] prices) {
        if (null == prices || prices.length < 2) {
            return 0;
        }

        final int n = prices.length;
        if (n <= k) {
            return maxProfit(prices);
        }

        int[][] global = new int[n][k + 1];
        int[][] local = new int[n][k + 1];

        for (int i = 1; i < n; ++i) {
            int diff = prices[i] - prices[i - 1];
            for (int j = 1; j <= k; ++j) {
                local[i][j] = Math.max(global[i - 1][j - 1] + Math.max(diff, 0), local[i - 1][j] + diff);
                global[i][j] = Math.max(global[i - 1][j], local[i][j]);
            }
        }
        return global[n - 1][k];
    }

    private int maxProfit(int[] prices) {
        final int n = prices.length;
        int maxProfit = 0;
        for (int i = 1; i < n; ++i) {
            maxProfit += prices[i] > prices[i - 1] ? (prices[i] - prices[i - 1]) : 0;
        }
        return maxProfit;
    }
```python # 导入requests和re模块 import requests import re # 设置请求头 headers ={ 'User-Agent': 'Mz1lla/5.e (Mindows NT 10.8; win64; x64) Chrome/69.0.3497.100 Safani/537.36'} # 定义一个函数,用于爬取百度新闻搜索结果 def baidu(company,page): # 根据页码计算出相应的条目数 num = (page - 1) * 18 # 构造请求URL url = 'https://www.baidu.com/s?tn=news&rtt=4&bsst=1&cl=2&wd'+ company +'&pn='+ str(num) # 发送GET请求,并获取响应内容 res = requests.get(url, headers =headers).text # 提取新闻信息 p_info = '<p class="c-author">(.*?)</p>' info = re.findall(p_info,res, re.S) # 提取新闻链接 p_href = '<h3 class="c-title">.*?<a href="(.*?)"' href = re.findall(p_href,res, re.S) # 提取新闻标题 p_title = '<h3 class="c-title“>.*?>(.*?)</a>' title = re.findall(p_title,res, re.S) # 存储新闻来源和发布时间 source = [] date = [] for i in range(len(info)): title[i] = title[i].strip() # 去除标题中的空格 title[i] = re.sub('<.*?>', '',title[i]) # 去除标题中的HTML标签 info[i] = re.sub('<.*?>', '', info[i]) # 去除信息中的HTML标签 source.append(info[i].split('  ')[0]) # 提取新闻来源 date.append(info[i].split( '  ')[1]) # 提取新闻发布时间 source[i] = source[i].strip() # 去除来源中的空格 date[i] =date[i].strip() # 去除时间中的空格 # 打印新闻标题、发布时间、来源、链接 print(str(i + 1)+'.'+ title[i]+'('+ date[i] +'-'+ source[i] + ')') print(href[i]) # 定义一个列表,存储要搜索的公司名称 companys = ['华能信托', '阿里巴巴', '万科集团', '百度集团', '腾讯','京东'] # 循环遍历每个公司名称,并爬取前20页的新闻搜索结果 for company in companys: for i in range(20): baidu(company,i+1) print(company+'第'+str(i+1)+'页爬取成功') ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值