剑指offer - 62.圆圈中最后剩下的数字 | 63.股票的最大利润

面试题62. 圆圈中最后剩下的数字

题目描述: 0,1,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。

例如,012345个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的
前4个数字依次是2041,因此最后剩下的数字是3。

示例 1:
输入: n = 5, m = 3
输出: 3

示例 2:
输入: n = 10, m = 17
输出: 2

解题思路:约瑟夫问题

递推公式:让f[i]为i个人玩游戏报m退出最后的胜利者的编号,最后的结果自然是f[n]
f[1] = 0;
f[i] = (f[i - 1] + m) mod i;
因为递推,所以可以不用保存状态;
class Solution {
public:
    int LastRemaining_Solution(unsigned int n, unsigned int m)
    {
         
        if(n <= 0 && m <= 0) return -1; 
        int t = 0;
        for(int i = 2; i <= n; i++)
            t = (t + m) % i;
        return t;
    }
};

面试题63. 股票的最大利润

题目描述: 假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?

示例 1:

输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
     注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。

示例 2:

输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0

解题思路:

1)把数组每个数减去前面的一个数,转化成一个差值数组,比如[7, 1, 5, 3, 6, 4]变成
[7,-6,4,-2,3,-2]。这样问题就转化成了:求一个数组区间,区间内所有数加起来最大。因为
 6 - 1 =6-3+(3-5) + (5-1)。 
(2)使用“大问题转化成小问题”的思路: 一个n长的数组的解如何跟n-1长数组的解联系起来?
如果在这两者之间建立联系,就可以把n长的一直转化成1长的问题,问题就直接解决了。
using namespace std;
int main() {
    system("pause");
    return 0;
}
//
int MaxDiff(const int *numbers, unsigned length) {
    if (numbers == NULL || length < 2)return 0;
    int min = numbers[0];
    int resu = numbers[1] - min;

    for (int i = 2; i != length; i++) {
        //检查前一天的值是不是最小值,是就更新最小值
        if (numbers[i-1] < min) {
            min = numbers[i-1];
        }
        //当前时间卖出能赚到最多的钱吗
        if ((numbers[i] - min) > resu) {
            resu = numbers[i] - min;
        }
    }
    return resu;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值