LeetCode每周五道面试题_2020/11/8~2020/11/12

文章目录

    • 122. 买卖股票的最佳时机 II [2020/11/08]
      • 题目
      • 示例
      • 代码模版
      • 题解
    • 973. 最接近原点的 K 个点 [2020/11/09]
      • 题目
      • 示例
      • 代码模版
      • 题解
    • 31. 下一个排列 [2020/11/10]
      • 题目
      • 题解
    • 514. 自由之路[2020/11/11]
      • 题目
      • 题解
    • 922. 按奇偶排序数组 II [2020/11/12]
      • 题目
      • 题解

122. 买卖股票的最佳时机 II [2020/11/08]

  • 122. 买卖股票的最佳时机 II

题目

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例

  • 示例 1:
输入: [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
     随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。
  • 示例2
输入: [1,2,3,4,5]
输出: 4
解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
     注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。
     因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
  • 示例3
输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

代码模版

/**
 * @param {number[]} prices
 * @return {number}
 */
var maxProfit = function(prices) {

};

题解

/**
 * @param {number[]} prices
 * @return {number}
 */
var maxProfit = function (prices) {
 let r = 0;
 prices.reduce((p, v) => {
   r += Math.max(0, v - p);//把后一项和前一项的差值为正数的相加,就是赚的最多的
   return v;
 });
 return r;
};

//简写版
var maxProfit = function(prices, r = 0) {
	let r=0;
    return prices.reduce((p,v)=>(r+=Math.max(0,v-p),v)),r
};

973. 最接近原点的 K 个点 [2020/11/09]

  • 973. 最接近原点的 K 个点

题目

我们有一个由平面上的点组成的列表 points。需要从中找出 K 个距离原点 (0, 0) 最近的点。

(这里,平面上两点之间的距离是欧几里德距离。)

你可以按任何顺序返回答案。除了点坐标的顺序之外,答案确保是唯一的。

示例

  • 示例 1:
输入:points = [[1,3],[-2,2]], K = 1
输出:[[-2,2]]
解释: 
(1, 3) 和原点之间的距离为 sqrt(10),
(-2, 2) 和原点之间的距离为 sqrt(8),
由于 sqrt(8) < sqrt(10),(-2, 2) 离原点更近。
我们只需要距离原点最近的 K = 1 个点,所以答案就是 [[-2,2]]。
  • 示例2
输入:points = [[3,3],[5,-1],[-2,4]], K = 2
输出:[[3,3],[-2,4]]
(答案 [[-2,4],[3,3]] 也会被接受。)
  • 提示:

1 <= K <= points.length <= 10000
-10000 < points[i][0] < 10000
-10000 < points[i][1] < 10000

代码模版

/**
 * @param {number[][]} points
 * @param {number} K
 * @return {number[][]}
 */
var kClosest = function (points, K) {

};

题解

/**
 * @param {number[][]} points
 * @param {number} K
 * @return {number[][]}
 */
var kClosest = function (points, K) {
    let arr = [];
    for (var i = 0; i < points.length; i++) {
        let temp = points[i];
        arr.push({
            id: Math.sqrt(
                Math.pow(Math.abs(temp[0]), 2) + Math.pow(Math.abs(temp[1]), 2)
            ),
            item: temp,
        });
    }
    return arr
        .sort((a, b) => {
            return a.id - b.id;
        })
        .map((item) => item.item)
        .slice(0, K);
};

31. 下一个排列 [2020/11/10]

  • 31. 下一个排列

题目

整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。
例如,arr = [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。
整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组的 下一个排列 就是在这个有序容器中排在它后面的那个排列。如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)。
例如,arr = [1,2,3] 的下一个排列是 [1,3,2] 。
类似地,arr = [2,3,1] 的下一个排列是 [3,1,2] 。
而 arr = [3,2,1] 的下一个排列是 [1,2,3] ,因为 [3,2,1] 不存在一个字典序更大的排列。
给你一个整数数组 nums ,找出 nums 的下一个排列。
必须 原地 修改,只允许使用额外常数空间。

题解

/**
 * @param {number[]} nums
 * @return {void} Do not return anything, modify nums in-place instead.
 */
var nextPermutation = function (nums) {
    let i = nums.length - 1 - 1;
    // 从右向左找到第一个降序位置
    while ((nums[i] >= nums[i + 1]) && i >= 0) {
        i--;
    }
    if (i >= 0) {
        //有降序节点
        let j = nums.length - 1;
        //从右往左找到一个刚好比降序节点大的值进行交换
        while (nums[j] <= nums[i]) {
            j--;
        }
        [nums[i], nums[j]] = [nums[j], nums[i]]
    }
    // 把降序节点右边的值(递减列)进行从小到大排序
    let l = i + 1, r = nums.length - 1;
    while (r > l) {
        if (nums[l] > nums[r]) {
            let value = nums[r];
            nums[r] = nums[l];
            nums[l] = value;
        }
        l++;
        r--;
    }
};

514. 自由之路[2020/11/11]

  • 514. 自由之路

题目

电子游戏“辐射4”中,任务 “通向自由” 要求玩家到达名为 “Freedom Trail Ring” 的金属表盘,并使用表盘拼写特定关键词才能开门。
给定一个字符串 ring ,表示刻在外环上的编码;给定另一个字符串 key ,表示需要拼写的关键词。您需要算出能够拼写关键词中所有字符的最少步数。
最初,ring 的第一个字符与 12:00 方向对齐。您需要顺时针或逆时针旋转 ring 以使 key 的一个字符在 12:00 方向对齐,然后按下中心按钮,以此逐个拼写完 key 中的所有字符。
旋转 ring 拼出 key 字符 key[i] 的阶段中:
您可以将 ring 顺时针或逆时针旋转 一个位置 ,计为1步。旋转的最终目的是将字符串 ring 的一个字符与 12:00 方向对齐,并且这个字符必须等于字符 key[i] 。
如果字符 key[i] 已经对齐到12:00方向,您需要按下中心按钮进行拼写,这也将算作 1 步。按完之后,您可以开始拼写 key 的下一个字符(下一阶段), 直至完成所有拼写。

题解

/**
 * @param {string} ring
 * @param {string} key
 * @return {number}
 */
var findRotateSteps = function (ring, key) {
  // 外环编码相同字母索引放到同一数组
  const ringMap = {};
  for (let i = 0; i < ring.length; i++) {
    const word = ring[i];
    if (ringMap[word]) {
      ringMap[word].push(i);
    } else {
      ringMap[word] = [i];
    }
  }

  // 重复计算会超时 由于 1 <= ring.length, key.length <= 100 所以可以搞个备忘录
  const memo = new Array(ring.length); //  相同编码索引开始,终点索引相同 直接取对应的最小步长

  function bfs(ringIndex, keyIndex) {
    if (keyIndex == key.length) return 0;
    const stepMemo = memo[ringIndex]?.[keyIndex];
    if (stepMemo) return stepMemo;
    // 字母对应外编码多个位置的数组
    const arr = ringMap[key[keyIndex]];
    let minStep = Infinity;
    // 找到这个字母不同位置、不同方向旋转最小的步长
    for (let item of arr) {
      // 同一个字母 不同方向移动步长
      const l =
        ringIndex - item >= 0
          ? ringIndex - item
          : ringIndex - item + ring.length;
      const r = ring.length - l;
      // 不同旋转方向最小步长
      const min = Math.min(l, r);
      minStep = Math.min(minStep, min + bfs(item, keyIndex + 1));
    }
    memo[ringIndex] = { ...memo[ringIndex], [keyIndex]: minStep };
    return minStep;
  }
  // 按下按钮需要一步,key个字母就是key.length
  return key.length + bfs(0, 0);
};

922. 按奇偶排序数组 II [2020/11/12]

  • 922. 按奇偶排序数组 II

题目

给定一个非负整数数组 nums, nums 中一半整数是 奇数 ,一半整数是 偶数 。
对数组进行排序,以便当 nums[i] 为奇数时,i 也是 奇数 ;当 nums[i] 为偶数时, i 也是 偶数 。
你可以返回 任何满足上述条件的数组作为答案 。

题解

/**
 * @desc 使用额外内存
 * @param {number[]} nums
 * @return {number[]}
 */
var sortArrayByParityII = function (nums) {
    const arr = [];
    let even = 0;
    let odd = 1;
    for (let i = 0; i < nums.length; i++) {
        if (nums[i] % 2 === 0) {
            arr[even] = nums[i];
            even += 2;
        }else{
             arr[odd] = nums[i];
            odd += 2;
        }
    }
    return arr;
};


/**
 * @desc 不用额外空间
 * @param {number[]} nums
 * @return {number[]}
 */
var sortArrayByParityII = function (nums) {
  let j = 1; // 奇数索引
  for (let i = 0; i < nums.length - 1; i += 2) {
    //数组中的偶数位置开始错误时
    if (nums[i] % 2 !== 0) {
      while (j < nums.length) {
        if (nums[j] % 2 === 1) {
          j += 2;
        } else {
          //奇数位置的值错误,和偶数错误值交换
          [nums[i], nums[j]] = [nums[j], nums[i]];
          j += 2;
          break;
        }
      }
    }
  }
  return nums;
};

你可能感兴趣的:(#,LeetCode每周五道面试题,leetcode,面试题,javascript)