• LeetCode 第 307 场周赛 复盘


    第一题、赢得比赛需要的最少训练时长

    题目:

    你正在参加一场比赛,给你两个 整数 initialEnergyinitialExperience 分别表示你的初始精力和初始经验。
    另给你两个下标从 0 开始的整数数组 energyexperience,长度均为 n
    你将会 依次 对上 n 个对手。第 i 个对手的精力和经验分别用 energy[i]experience[i] 表示。当你对上对手时,需要在经验和精力上都 严格 超过对手才能击败他们,然后在可能的情况下继续对上下一个对手。
    击败第 i 个对手会使你的经验 增加 experience[i],但会将你的精力 减少 energy[i]
    在开始比赛前,你可以训练几个小时。每训练一个小时,你可以选择将增加经验增加 1 或者 将精力增加 1 。

    返回击败全部 n 个对手需要训练的 最少 小时数目。

    示例:

    输入:initialEnergy = 5, initialExperience = 3, energy = [1,4,3,2], experience = [2,6,3,1]
    输出:8
    解释:在 6 小时训练后,你可以将精力提高到 11 ,并且再训练 2 个小时将经验提高到 5 。
    按以下顺序与对手比赛:

    • 你的精力与经验都超过第 0 个对手,所以获胜。
      精力变为:11 - 1 = 10 ,经验变为:5 + 2 = 7 。
    • 你的精力与经验都超过第 1 个对手,所以获胜。
      精力变为:10 - 4 = 6 ,经验变为:7 + 6 = 13 。
    • 你的精力与经验都超过第 2 个对手,所以获胜。
      精力变为:6 - 3 = 3 ,经验变为:13 + 3 = 16 。
    • 你的精力与经验都超过第 3 个对手,所以获胜。
      精力变为:3 - 2 = 1 ,经验变为:16 + 1 = 17 。
      在比赛前进行了 8 小时训练,所以返回 8 。
      可以证明不存在更小的答案。

    输入:initialEnergy = 2, initialExperience = 4, energy = [1], experience = [3]
    输出:0
    解释:你不需要额外的精力和经验就可以赢得比赛,所以返回 0 。

    这一题很简单,只需要初始精力大于精力总和即可(大1),然后就是遍历 experience 保证初始经验在累加过程中始终大于该值即可 。
    要求的是最少*小时数目,所以只需要大于1即可。
    下面是代码:

    var minNumberOfHours = function(initialEnergy, initialExperience, energy, experience) {
        let needEnergy = 0, needExper = 0;
        needEnergy = energy.reduce((pre, cur) => pre+cur, 1)- initialEnergy;
        
        for(let i = 0;i<experience.length;i++) {
            if(initialExperience <= experience[i]) {
                needExper += experience[i] - initialExperience + 1;
                initialExperience += needExper;
            }
            initialExperience += experience[i];
        }
        return needExper + needEnergy;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    但是,提交之后会有一个示例过不去😅,而且不给显示那个具体的案例😅。

    为保障竞赛的公平性,力扣将在竞赛中隐藏部分用例。当参赛者在竞赛中提交未通过时,力扣不会显示给参赛者被隐藏的错误用例。

    痛,太痛了。找了半天才发现是我的所需精力的算法有问题,needEnergy = energy.reduce((pre, cur) => pre+cur, 1)- initialEnergy; 这句,初始精力有可能大于energy的总和,所以可能会出现负值,但是根据题意,需要将其变为 0。
    最终代码:

    /**
     * @param {number} initialEnergy
     * @param {number} initialExperience
     * @param {number[]} energy
     * @param {number[]} experience
     * @return {number}
     */
    var minNumberOfHours = function(initialEnergy, initialExperience, energy, experience) {
    
        let needEnergy = 0, needExper = 0;
        needEnergy = energy.reduce((pre, cur) => pre+cur, 1)- initialEnergy;
        if(needEnergy < 0) {
            needEnergy = 0;
        }
        
        for(let i = 0;i<experience.length;i++) {
            if(initialExperience <= experience[i]) {
                needExper += experience[i] - initialExperience + 1;
                initialExperience += needExper;
            }
            initialExperience += experience[i];
        }
        return needExper + needEnergy;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    第二题、最大回文数字

    给你一个仅由数字(0 - 9)组成的字符串 num 。
    请你找出能够使用 num 中数字形成的 最大回文 整数,并以字符串形式返回。该整数不含 前导零 。
    注意:

    • 你 无需 使用 num 中的所有数字,但你必须使用 至少 一个数字。
    • 数字可以重新排序。

    示例1:
    输入:num = “444947137”
    输出:“7449447”
    解释:
    从 “444947137” 中选用数字 “4449477”,可以形成回文整数 “7449447” 。
    可以证明 “7449447” 是能够形成的最大回文整数。

    示例 2:
    输入:num = “00009”
    输出:“9”
    解释:
    可以证明 “9” 能够形成的最大回文整数。
    注意返回的整数不应含前导零。

    这一题我也调试了半天才过😅

    解题思路:

    • 首先创建一个长为10(0~9)的数组用于保存对应数字(下标)的个数。然后遍历num将对应数字的个数存入数组map
    • 题目要求的是最大回文整数,所以从大到小遍历数组map,如果有个数字的数量大于等于2,即可放入结果数组ans中,然后将其去掉2个。
    • 由于要求 不应含前导零 ,所以当结果数组ans中无数字且遍历到0时,应掠过0
    • 接着需要找到一个中间数,即找到遍历后的数组中的最大值加入进去。
    • 最后将结果数组ans复制一份,反转加到ans尾部;拼接起来就是结果。

    然后就是经典差一个示例不过😅,排查起来才发现是回文中间不一定会有单个数,也有可能没有,所以要加个变量判断是否要加(数组是否还剩数)。

    /**
     * @param {string} num
     * @return {string}
     */
    var largestPalindromic = function (num) {
      let map = new Array(10).fill(0);
      for (let i = 0; i < num.length; i++) {
        map[num[i]]++;
      }
      let ans = [], isInsert = true;
      for (let i = 9; i >= 0; i--) {
        if (ans.length === 0 && i == 0) {
          continue;
        }
        while (map[i] >= 2) {
          ans.push(i);
          map[i] -= 2;
        }
      }
      for (let i = 9; i >= 0; i--) {
        if(map[i] === 0) {
          isInsert = false;
        } else {
          isInsert = true;
          ans.push(i);
          break;
        }
      }
      const a = ans.slice().reverse();
      if( isInsert) {
        ans.push(...a.slice(1));
      } else {
        ans.push(...a.slice());
      }
      return ans.join("");
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    后两题

    什么,你问后两题咋没有?那我只能说本人菜鸟一个,只能做出前两题😅😅😅

    经过不懈的努力(摆烂),本人已经是力扣周赛基本稳定2题的选手,正在冲击第三题。

    下面给出后两题链接,希望有大佬给讲解一下🤣

    来源:力扣(LeetCode)
    链接:https://leetcode.cn
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

  • 相关阅读:
    京东二面:高并发设计,都有哪些技术方案?
    【无标题】
    14:00面试,14:06就出来了,问的问题有点变态。。。
    React 学习系列: 类组件生命周期方法
    [红蓝攻防]MDOG(全新UI重制版)为Xss跨站而生,数据共享,表单劫持,URL重定向
    python实现对excel表中的某列数据进行排序
    【Java】继承练习
    CRC校验码
    React
    vue3 Component API
  • 原文地址:https://blog.csdn.net/qq_46590483/article/details/126451778