JS算法之圆圈中最后剩下的数字及股票的最大利润

292 阅读2分钟

这是我参与11月更文挑战的第18天,活动详情查看:2021最后一次更文挑战

圆圈中最后剩下的数字

剑指Offer 62. 圆圈中最后剩下的数字

难度:简单

题目:leetcode-cn.com/problems/yu…

0,1,...,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字(删除后从下一个数字开始计数)。求出这个圆圈里剩下的最后一个数字。

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

示例1:

输入: n = 5, m = 3
输出: 3

示例2:

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

限制:

  • 1 <= n <= 10^5
  • 1 <= m <= 10^6

题解

动态规划

本质上这道题就是一个约瑟夫环。n个人编号0~n-1,每数m次删掉一个人。使用f(n)f(n)表示n个人最终剩下人的编号。

n个人删掉的第一个人的编号是(m1)%n(m-1)\%n,其之后的人编号为(m1+1)%n(m-1+1)\%nm%nm\%n是下一个约瑟夫环的编号为0的那个人,n-1个人时编号为ii的人就是n个人时(m+i)%n(m+i)\%n

因此得出f(n)=(m+f(n1))%nf(n)=(m+f(n-1))\%n,1个人时只有一个编号0,f(1)=0f(1)=0

因此动态规划转移方程为:

dp[i]=(dp[i1]+m)%idp[i] = (dp[i-1]+m)\%i

代码如下:

/**
 * @param {number} n
 * @param {number} m
 * @return {number}
 */

var lastRemaining = function (n, m) {
  let ans = 0;
  for (let i = 2; i <= n; i++) {
    ans = (ans + m) % i;
  }
  return ans;
};
  • 时间复杂度:O(NN)
  • 空间复杂度:O(11)

股票的最大利润

剑指Offer 63. 股票的最大利润

难度:中等

题目:leetcode-cn.com/problems/gu…

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

示例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。

限制:0 <= 数组长度 <= 10^5

题解

法一 暴力法

两层for循环,直接暴力出最大利润。

/**
 * @param {number[]} prices
 * @return {number}
 */
var maxProfit = function (prices) {
  let res = 0;
  for (let i = 0; i < prices.length; i++) {
    for (let j = i + 1; j < prices.length; j++) {
      res = Math.max(res, prices[j] - prices[i])
    }
  }
  return res;
};
  • 时间复杂度:O(N2N^2)
  • 空间复杂度:O(11)

法二 动态规划

状态定义:设dp[i]为以prices[i]为结尾的子数组的最大利润(即前i日的最大利润)。

转移方程:前i日最大利润dp[i]为前一天的最大利润dp[i-1]和第i天卖出利润prices[i]-min(prices[0:i])的最大值,状态方程如下:

dp[i]=max(dp[i1],prices[i]min(prices[0:i]))dp[i]=max(dp[i-1],prices[i]-min(prices[0:i]))

因为这里的dp[i]只与dp[i-1]有关,这里的dp其实可以用一个变量去取代。

var maxProfit = function (prices) {
  let dp = 0,cost = Infinity;
  for(let i = 0; i < prices.length; i++){
    cost = Math.min(cost,prices[i]);
    dp = Math.max(dp,prices[i] - cost);
  }
  return dp;
};
  • 时间复杂度:O(NN)
  • 空间复杂度:O(11)

坚持每日一练!前端小萌新一枚,希望能点个哇~