笔试|做过的笔试题的题解积累🏆🏆🏆

863 阅读7分钟

小红书

零件组装

小明管理了一家工厂,该工厂生产一种大型机械,需要由四种零件组力完成我们不妨称这四种零件为A,B,C,D.

由于生产机械需要保证产品的质量,工厂对每个零件会进行检测,量化出每个零件的评分,评分当然有一个合格的分数(我们不妨假设它是x),当零件译分大于x的时候,该零件才是合格的。

四个分别合格的零件A,B,C,D可以组装成一个合格的大型机械。现在小明想如道当前产出的这些零件一共可以组装成多少合格的大型机城? 请注意:每个零件至多只能用于一个大型机械的组装,不能反复组装

幅一行五个正梦数,前四个正整数a1,a2,a3,a4分别表示有a1个零件A,a2个零件B,a3个零件C,a4个零件D,第五个正整数示合格的零件评分需要大于x.

接下来4行:

前二行有a1个空格分开的数字,分别表示这a1个零件A的评分。

航三行有a2个空格分开的数字,分别表示这a2个零件B的评分。

第四行有a3个空格分开的数字,分别表示这a3个零件C的评分。

第五行有a4个空格分开的数字,分别表示这a4个零件D的评分。

输入

1 2 2 1 2
4
7 7
6 6
8

输出

1

这个题的思路,很简单那,就是求数组中,数组元素大于这个标准的x的个数,求出来之后,找到最小值就可以了,但是我的比例只有55%,我不知道怎么回事,但是我感觉思路没有问题 ,我不能理解🌟

let x = 4;
let arr = [
 [4, 4, 4],
 [7, 7],
 [6, 6],
 [8, 8],
];
let obj = {};
for (let i = 0; i < arr.length; i++) {
 let count = 0;
 for (let j = 0; j < arr[i].length; j++) {
   if (arr[i][j] > x) {
     count++;
   }
 }
 obj[i] = count;
}

let res = Object.values(obj);
let t = Math.min(...res);
console.log(t);


支配数

小A认为如果在数组中有一个数出现了至少k次且这个数是该数组的众数(团出现次数最多的数之一)那么这个数组被该数所支配。显然,当ki比较大的时候有些数组不被任何数所支配。现在小A想知道她所拥有的数组A中有多少个区间是被某个数所支配的。

第一行有两个正整数n,k(2<=k<=n<=100000).nf代表小A所拥有的数组A的长度,k代表问题描述中的参数。

第二行有n个正整数,代表A中元素的值。值的范围在1到n之同。

一个非负整数,代表所求的答案,

输入

6 2
1 2 1 3 2 3

输出

8
输入中[1,2,1][1,2,1,3][1,2,1,3,2] [1,2,1,3,2,31[2,1,3,2] [2,1,3,2,3][1,3,2,3]

[3,2,3]这8个区间均被分别被某些数所支配。

这个题当时做的时候是有思路的,主要是有一个函数判断数组中是否存在被支配的数,如果存在,返回true

这里巧妙的是,切割数组区间,针对这个题目来说

如果小区间存在这个可支配的数,那就不需要在遍历了,后面扩展的大区间是一定符合的,直接返回剩余可以扩展的长度就好了,当时我这里想的不够清楚,通过率只有55%,又是55%💥,下面这个代码是我考虑清楚之后的,我认为是可以的,可是我没有机会去试了😤

let n = 6;
let k = 2;
let res = 0;
let arr = [1, 2, 1, 3, 2, 3];
function hasKing(nums, k) {
  let map = new Map();
  for (let i of nums) {
    map.set(i, map.has(i) ? map.get(i) + 1 : 1);
  }
  let keys = map.keys();
  let max = map.get(nums[0]);
  for (let i of keys) {
    if (map.get(i) > max) max = map.get(i);
  }
  return max >= k;
}
for (let i = 0; i < n; i++) {
  for (let j = k + i; j < n; j++) {
    let temp = arr.slice(i, j + 1);
    if (hasKing(temp, k)) {
      // 这里有一个思想就是 如果在小区间已经找到了,那就没有必要往大区间遍历,直接计算剩余长度就好了
      res = res + n - j;
      break;
    }
  }
}
console.log(res);

大疆

剑指 Offer II 035. 最小时间差

给定一个 24 小时制(小时:分钟  "HH:MM" )的时间列表,找出列表中任意两个时间的最小时间差并以分钟数表示。

示例 1:

输入: timePoints = ["23:59","00:00"]
输出: 1

示例 2:

输入: timePoints = ["00:00","23:59","00:00"]
输出: 0

思路:

求分钟差,就先转成分钟,数组中是字符串可以先截取,在数组化,转成分钟之后可以把数组升序排列,得到一个有序的分钟数组

这个时候可以思考💡:既然是求最小值,那相邻的肯定最近了,也就是差值最小了,但是还差最后一个和第一个的比较,因为题目要求是列表中任意两个时间,那就遍历对比数组的相邻两项,得到一个差值数组

考虑特殊的就是最后一个和第一个

把差值数组升序,arr[0]就是我们的结果值了

注意🌟:这里有一个细节需要考虑,就是24小时制的问题比如这个例子["00:00","23:59"],其实只差一分钟,但是我们如果只做差值的话,那必然是一个非常大的数字,而不是1,所以这里需要1440(24小时*60 = 1440)减去差值

var findMinDifference = function (timePoints) {
    // 分钟数组
    let minArray = timePoints.map((item) => {
        return parseInt(item.substr(0, 2)) * 60 + parseInt(item.substr(3, 2))
    }).sort((a, b) => {
        return a - b;
    })
    // 差值数组
    let diffArray = [];
    minArray.forEach((item, i) => {
        if (i > 0) {
            diffArray.push(Math.min(minArray[i] - minArray[i - 1], 1440 - (minArray[i] - minArray[i - 1])))
        }
    })
    // 首尾差
    let lastChild = minArray[minArray.length - 1] - minArray[0]
    diffArray.push(Math.min(lastChild, 1440 - lastChild))
    diffArray.sort((a, b) => {
        return a - b;
    })
    return diffArray[0];
}

let timePoints = ["04:00", "23:59", "00:00"];
console.log(findMinDifference(timePoints));

1675. 数组的最小偏移量

给你一个由 n 个正整数组成的数组 nums 。

你可以对数组的任意元素执行任意次数的两类操作:

如果元素是 偶数 ,除以 2

例如,如果数组是 [1,2,3,4] ,那么你可以对最后一个元素执行此操作,使其变成 [1,2,3,2] 如果元素是 奇数 ,乘上 2

例如,如果数组是 [1,2,3,4] ,那么你可以对第一个元素执行此操作,使其变成 [2,2,3,4] 数组的 偏移量 是数组中任意两个元素之间的 最大差值 。

返回数组在执行某些操作之后可以拥有的 最小偏移量 。

示例 1:


输入:nums = [1,2,3,4]

输出:1

解释:你可以将数组转换为 [1,2,3,2],然后转换成 [2,2,3,2],偏移量是 3 - 2 = 1

示例 2:


输入:nums = [4,1,5,20,3]

输出:3

解释:两次操作后,你可以将数组转换为 [4,2,5,5,3],偏移量是 5 - 2 = 3

示例 3:

输入:nums = [2,10,8]
输出:3

思路:

我们可以操作增加数组,那我们就把所有的奇数都变成最大偶数,这样之后的操作就只能用除法,每次操作都用最大值去做除法,拉小最大值和最小值的差距,这样偏移量就会越来越小。


// java

class Solution {
    public int minimumDeviation(int[] nums) {
        // TreeSet默认有序 
        TreeSet<Integer> set = new TreeSet<>();
        // 先放大奇数,因为奇数*2 之后会变成偶数,就只能/2 进行缩小了
        // 所以奇数*2 ,偶数不变
        for(int num : nums){
            set.add(num % 2 == 0 ? num : num*2);
        }
        // 先暂时存一个最大的偏移量,为什么说是最大的,因为set默认升序的
        int diff = set.last() - set.first();
        // 只要最大值是偶数,就可以缩小
        while(set.last() % 2== 0){
            int tempMax = set.last();
            // 去除最大的
            set.remove(tempMax);
            // 最大值偶数,进行/2
            tempMax = tempMax /2;
            // 放回/2 的值,此时set会自动排序,最大值可能变更了
            set.add(tempMax);
            //获取此时的偏移量
            int tempDiff = Math.min(diff,set.last()- set.first());
            // 偏移量已经是最小了
            if(tempDiff < 0) break;
            // 更新偏移量
            diff = tempDiff;

        }
        return diff;
    }
}

未命名文件.png


//js版本 但是leetcode运行超时了

/**
 * 排序函数
 * @param {*} arr 
 * @returns 
 */
function sort(arr) {
    return arr.sort((a, b) => {
        return a - b;
    })
}
/**
 * 数组的最小偏移量
 * @param {*} arr 
 * @returns 
 */
function minimumDeviation(arr) {
    // 放大数组
    let maxArr = arr.map((item) => {
        return item = item % 2 === 0 ? item : item * 2;
    })
    // 排序
    sort(maxArr);
    let maxVal = maxArr[maxArr.length - 1]
    let minVal = maxArr[0];
    let diff = maxVal - minVal;
    // 最大值是偶数
    while (maxVal % 2 === 0) {
        // 出队最大元素
        let temp = maxArr.pop();
        // 缩小最大元素
        let tempVal = temp / 2;
        // 放入数组
        maxArr.push(tempVal);
        // 排序
        sort(maxArr);
        // 最小差值
        let tempDiff = Math.min(diff, maxArr[maxArr.length - 1] - maxArr[0]);
        if (tempDiff < 0) break;
        diff = tempDiff;
        // 重新获取最大值
        maxVal = maxArr[maxArr.length - 1];
    }
    return diff;
}
let nums = [1, 2, 3, 4];
console.log(minimumDeviation(nums));

蔚来

总共有多少个‘0’

小红想知道,n的阶乘十进制表示总共有多少个‘0’

思路:先求出n的阶乘,然后遍历0的个数即可。

示例 1:


输入:7

输出:2

解释:7的阶乘是5040,其中有2个数字0

动态回文

小红拿到一个字符串,她准备删除其中一段区间,使得剩下的部分是回文

小红希望得到的字符串长度尽可能的大,你能求出这个长度吗?


输入:abca

输出:3

解释:删除区间[2,2],形成字符串aca是回文的

输入:cbcbacabb

输出:3

解释:删除区间[4,9],形成字符串cbc是回文的,可以证明,无法得到更长的回文串
/**
 * 切割字符串
 */
function cutString(str) {
  let arr = str;
  let maxLen = 0;
  for (let i = 0; i < arr.length; i++) {
    for (let j = i; j <= arr.length; j++) {
        let cut = arr.split("");
      // 删除某段区间
      cut.splice(i, j);
      if (judgmentpPalindrome(cut)) {
        maxLen = Math.max(maxLen, cut.length);
      }
    }
  }
  return maxLen;
}
/**
 * 判断回文
 */
function judgmentpPalindrome(arr) {
  let i = 0;
  let j = arr.length - 1;
  while (i < j) {
    if (arr[i] !== arr[j]) {
      return false;
    }
    i++;
    j--;
  }
  return true;
}
let str = "google";
console.log(cutString(str));

山洞探险

牛牛和牛妹一起去爬山,途中,有一个名为《山洞探险》的游乐项目,本来已经精疲力竭的他们瞬间焕发出了活力。 《山洞探险》项目介绍: 首先,游玩者可以任意规定山门的颜色。 由山门进入山洞,该山洞一共分为n层,每一层有两扇带有颜色的门,这两扇门都可以通往下一层,但游玩者只能从这两扇门中选择扇打开。 如果游玩者当前选择打开的门与上一层打开的门的颜色相同,则不需要花费任何代价就可以打开这扇门;而如果颜色不相同,则游玩要花费一定时间进行破译,破译完成后才能打开门进入下一层。(特殊的,如果当前是第一层,则上一层打开的门的颜色由山门的颜色代替)当游玩者打开n扇门走出山洞之后,该游乐项目负责人会根据该游玩者所花费的破译时间进行颁发奖品,时间越短的奖品越好。

为了方便计算,游乐项目负责人首先会将山门可能出现的m种颜色从1~m编号,而破译时间则定义为:上一层打开的门的颜色编号(若当前是第一层,则这里指山门的颜色编号)×当前这一层想要打开的门的颜色编号。

牛牛和牛妹十分想要山洞后的奖品,所以他们请你事先计算一下游玩该项目最少所需要花费的破译时间是多少,以此来决定自己是否参加

第一行2个数,n,m代表山东层数和颜色种类

示例1:


输入:

3 3
1 3
2 1
2 3

输出:2

let list = [[33], [13], [21], [23]];
        let floor = list[0][0];
        let color = list[0][1];
        let result = 0;
        var stack = function (time1, color2, index) {
            if (index == (floor + 1)) {
                let result2 = 0;
                time1.forEach(item => result2 += item)
                result = result == 0 ? result2 : Math.min(result2, result);
                return;
            };
            if (index > floor) return;
            for (let i = 0; i < 2; i++) {
                if (color2 != list[index][i]) {
                    time1.push(color2 * list[index][i]);
                }
                stack(time1, list[index][i], ++index);
                time1.pop(); index--;
            }
        }
        stack([], null1)
        console.log(result)

zoom

嘲笑问题

tom和jerry玩游戏关卡


输入:
5

1 2 3 1 3

1 2 5 1 3

5代表总共5关,第二行是tom的得分,第三行是jerry的得分

比如tom第一关是1,第二关是2 tom的嘲笑分是1 

jerry第一关是1,第二关是3,jerry的嘲笑分是2

此时,jerry可以嘲笑tom,如果嘲笑分相等,则互相不嘲笑,嘲笑分高的可以嘲笑分低的

问,可以修改tom的分数,使得2个人互相不嘲笑,最小的修改次数是多少

输出:1

解释:

此时只要将tom的第三关分数改成5,2个人就可以不嘲笑了

2 学生会会长

记不太清了,算什么能管理的总和,需要根据条件构造出树,然后在算管理成本

4399

css实现某个动画

请补齐代码实现以下效果

1、btn (id为btn的元素)相对于box (id为box的元素)水平、垂直方向居中显示

2、进入页面时,btn循环360度旋转,1秒旋转—圈

3、鼠标进入btn区域时,停止旋转,鼠标退出btn时继续旋转

<style>
.box {
width: 600px;height: 600px;
.btn {
width: 100px;height: 100px;}
< /style>
<script>
<div class="box"></div>
<div class="btn"> </div>
</script>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .box {
            position: relative;
            width: 600px;
            height: 600px;
            background-color: bisque;
        }

        .btn {
            background-color: blue;
            position: absolute;
            width: 100px;
            height: 100px;
            left: 50%;
            top: 50%;
            margin-left: -50px;
            margin-top: -50px;
            animation: test 1s linear infinite;
        }

        @keyframes test {
            from {}

            to {
                transform: rotate(360deg);
            }
        }
    </style>
</head>

<body>
    <div id="box" class="box">
        <div class="btn" id="btn"></div>
    </div>
    <script>
        let btn = document.getElementById('btn')
        btn.addEventListener('mouseenter', () => {
            btn.style.animationPlayState = "paused"
        })
        btn.addEventListener('mouseleave', () => {
            btn.style.animationPlayState = "running"
        })
    </script>
</body>

</html>

3.gif

解析url地址

现有一函数parseUrlParam,其功能是解析网站url地址,并返回一个js对象urlObject

function parseUrlParam(url){

//你的代码


return urlObject;


let url = 'http://www.4399.com/?user=candidate&id=438id=998city=%E5%B9%BF%E5%B7%9E&enabled;parseUrlParam(url)


//输出结果
{ user: 'candidate" ,
id: [ 43,99 ],//重复出现的 key要组装成数组,能被转成数字的就转成数字类型
city: "广州',//中文需解码
enabled: true,/*未指定值得key 约定为true*/
}

第一个不重复的字符

给定一个字符串s,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回-1,请按以上要求完善solution(s)函数

示例1:
输入:s = "javascript"
输出:0
示例2:
输入:s = "javajavascript"
输出:8
示例3:
输入: s = "aabb"
输出: -1

lastIndexOf

最简单的方法,lastIndexOf返回指定字符在此字符串中最后一次出现处的索引,那就好办了,如果第一次索引和最后一次索引一致,那说明是第一次出现的,如果没有,那就返回-1

function findFirst(str) {
    for (let ind in str) {
        if (str.indexOf(str[ind]) === str.lastIndexOf(str[ind]))
            return ind
    }
    return -1
}
console.log(findFirst('javascript')); // 0
console.log(findFirst('aabb')); // -1
console.log(findFirst('javajavascript')); // 8

遍历字符串2次

思路:遍历字符串2次,第一次统出各个字符串出现的次数,第二次按照顺序找到最先只出现1次的 js中字符不能相减,要利用String.charCodeAt(i) 获取字符的ascii码

function findFirst(str) {
    let arr = new Array(26).fill(0);
    let count = 0;
    let str2 = "a";
    let n = str2.charCodeAt(0);
    for (let i = 0; i < str.length; i++) {
        // 'j' - 'a' = 106 - 97 = 9
        let temp = (str.charCodeAt(i) - n);
        arr[temp]++;
    }
    for (let i = 0; i < str.length; i++) {
        if (arr[(str.charCodeAt(i) - n)] === 1) {
            return i;
        }
    }
    return -1;
}
console.log(findFirst('javascript')); // 0
console.log(findFirst('aabb')); // -1
console.log(findFirst('javajavascript')); // 8

obj:{x:[a,b]}

利用obj:{x:[a,b]} 的形式记录只字符串,x是字符,a是出现次数,b是下标

function findFirst(str) {
    let obj = {};
    for (let i = 0; i < str.length; i++) {
        if (str[i] in obj) {
            let temp = obj[str[i]];
            // 下标+1
            temp[0] += 1;
            obj[str[i]] = temp;
        } else {
            obj[str[i]] = [1, i]
        }
    }
    let arr = Object.keys(obj);
    for (let i = 0; i < arr.length; i++) {
        let z = obj[arr[i]]
        if (z[0] === 1) {
            return z[1];
        }
    }
    return -1;
};
console.log(findFirst('javascript')); // 0
console.log(findFirst('aabb')); // -1
console.log(findFirst('javajavascript')); // 8

好未来

最多的字符及其个数

给定一个非空字符串str,请实现一个函数getMaxLengthChar,返国s字符串中出现最多的字符及其个数。

思路:这个很简单,用一个对象存储一下,遍历一道数组,在输出最大的值和key值就可以了

版本号排序

versions是一个项目的版本号数组(非空),每个版本号由以小数点分隔的三个非负整数组成(如,'1.22.3'),现需要你写一个函数 sortVersions对版本号进行从小到大排序。要求对versions从小到大排序,注意'1.45.1比1.5.0大, "10.0.119.99.9'大,0.0.2'比0.0.1大.

输入:

["1.45.1","1.5.0"]

输出:

1.5.0,1.45.1

思路:这个题其实也简单,拿到数组的值之后,按照'.'分割一下,进行大小比较即可,但是恶心的是,处理输入输出

因为接进来的数据,按照','分割之后,arr[0] = ["1.45.1" arr[1]= "1.5.0"]所以需要将字符串中的其他字符处理掉

/**
 * 处理字符串数组
 * @param {*} str 
 * @returns '["1.45.1","1.5.0"]' ===> ['1.45.1','1.5.0']
 */
function handle(str) {
    // 分割字符串
    let arr = str.split(',')
    // console.log("arr[0]=", arr[0], "arr[1]=", arr[1]); // arr[0]= ["1.45.1" arr[1]= "1.5.0"]
    let res = [];
    // 将每一个字符串中的" [ ] 都替换掉
    arr.forEach(ele => {
        let c = ele.replace(/[\[\]\"]/g, '')
        res.push(c)
    })
    return strSort(res)
}
/**
 * 排序比大小
 * @param {*} list 
 * @returns 
 */
function strSort(list) {
    // list = ['1.45.1','1.5.0'] a = 1.45.1 b = 1.5.0
    return list.sort((a, b) => {
        let a1 = a.split('.');
        let b1 = b.split('.');
        // 分割之后,就变成了 1和1 45和5 1和0 分别比较
        if (a1[0] != b1[0]) {
            return a1[0] - b1[0];
        } else if (a1[1] != b1[1]) {
            return a1[1] - b1[1]
        } else {
            return a1[2] - b1[2]
        }
    })
}
let str = '["1.45.1","1.5.0"]'
let print = handle(str)
console.log(print);

360

DNA串

有一种DNA由A和T组成,长度为n,顺次连接。现有一种手段可以改变这种DNA:每一次可以交换DNA上两个核酸的位置,也可以将某个特定位置的核酸修改为另一种核酸。现有一种DNA,希望将它改造成另一种DNA,计算最少的操作次数。

输入:两行DNA 输出:第一行DNA改为第二行DNA的最少修改次数

ATTTAA
TTAATT

输出:3

// java版本
import java.util.Scanner;
 
public class First {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String old = sc.nextLine();
        String newStr = sc.nextLine();
        int oldA = 0, newStrA = 0, tong = 0;
        for(int i = 0; i < old.length(); i++){
            if(old.charAt(i) == 'A'){
                oldA++;
                if(newStr.charAt(i) == 'A'){
                    tong++;
                    newStrA++;
                    continue;
                }
            }
            if(newStr.charAt(i) == 'A'){
                newStrA++;
            }
        }
        if(oldA > newStrA){
            System.out.println(oldA - tong);
        } else {
            System.out.println(newStrA - tong);
        }
    }
}

老张修路

using namespace std;

    int main() {
        //通用图数据存储
        int n, m;
        cin >> n;
        cin >> m;
        int u, v;//入边,出边
        vector<vector<int>> edge(n, vector<int>(n));
        for (int i = 0; i < m; ++i) {
            cin >> u >> v;
            cin >> edge[u][v];//这是邻接矩阵
            edge[v][u] = edge[u][v];
        }
        unordered_map<int,int> mp;//存已经加入的边
        vector<int> vt;
        //prim开始
        mp[0] = 1;
        vt.push_back(0);
        int ans = 0;
        int minLen;
        int node;
        for (int i = 0; i < n - 1; ++i) {
            minLen = INT_MAX;
            node = -1;
            for (auto e1:vt) {//for e1 in vt,离已选点最近的点加进来
                for (int k = 0; k < n; ++k) {
                    if (mp[k]) continue;
                    else if (edge[e1][k] == 0) continue;//无边
                    else {
                        if (edge[e1][k] < minLen) {
                            node = k;
                            minLen = edge[e1][k];
                        }
                    }
                }
            }
            ans += minLen;
            mp[node] = 1;
            vt.push_back(node);
        }
        for (auto num : vt) {
            cout << num << endl;
        }
        cout << ans << endl;

    }

bilibili

leetcode 72

题:给定两个字符串 word1 和 word2 ,计算出将 word1 转化为 word2 所使用的最少操作数。

输入: word1 = "horse", word2 = "ros"
输出: 3
解释: 
horse -> rorse (将 'h' 替换为 'r')
rorse -> rose (删除 'r')
rose -> ros (删除 'e')
public class Solution {
    public int minDistance(String word1, String word2) {
        if(word1.equals(word2))
            return 0;
        if(word1.length() == 0 && word2.length() != 0)
            return word2.length();
        if(word1.length() == 0 && word2.length() != 0)
            return word2.length();
        //dp[i][j]表示word1的前i个字符转变成word2的前j的字符所需的步数
        int[][] dp = new int[word1.length() + 1][word2.length() + 1];
        dp[0][0] = 0;
        for(int i = 1; i <= word1.length(); i++){
            dp[i][0] = i;
        }
        for(int j = 1; j <= word2.length(); j++){
            dp[0][j] = j;
        }
        for(int i = 1; i <= word1.length(); i++){
            for(int j = 1; j <= word2.length(); j++){
                //字符相等,则直接跳过
                if(word1.charAt(i-1) == word2.charAt(j-1))
                    dp[i][j] = dp[i-1][j-1];
                //字符不相等,则需要进行一步操作,要取所有情况下的最小值
                else
                    dp[i][j] = Math.min(Math.min(dp[i][j-1] + 1, dp[i-1][j] + 1), dp[i-1][j-1] + 1);
            }
        }
        return dp[word1.length()][word2.length()];
    }
}

括号问题

返回缺失的括号和位置

美团

奇安信

中文在线

百奥

灯泡

银行排队窗口

var w = 3, timerArr = [20, 5, 10, 20, 5, 5];
var list = new Array(w).fill(0);
var result = ''
timerArr.forEach((value, id) => {
    if (list.includes(0)) {
        let t;
        let id1 = list.findIndex((item) => item === 0)
        result += (id1 + 1).toString();
        list[id1] = value;
    } else {
        let b1
        let a1 = list.reduce((pre, a, b) => {
            if (pre > a) {
                b1 = b
                pre = a;
            }
            return pre;
        })
        result += (b1 + 1).toString()
        list[b1] += value
        console.log(list);
    }
})
console.log(result)


function solution(w, timeArr) {
    let arr = [];
    for (let i = 0; i < w; i++) { // 先把w个人依次排到窗口前
        arr[i] = i + 1;
    }
    let res = arr; // 返回值
    let arrTemp = timeArr.slice(0, w); // 截取前w个人的时间
    let list = timeArr.slice(w); // 截取后w个人的时间
    let idx; // 最小值的index
    while (list.length) { // 一直有人排队
        arrTemp.reduce((pre, cur, index) => {
            if (pre > cur) {
                pre = cur; // 最小值
                idx = index;
            }
            return pre;
        })
        res.push(idx + 1); // 去最小值窗口排队
        arrTemp[idx] += list.shift(); // 最小窗口的时间增加
    }
    return res.join('');
}
let w = 3;
let timerArr = [20, 5, 10, 20, 5, 5];
console.log(solution(w, timerArr));

三角形最小路径和

public class Solution {
    public int minimumTotal(List<List<Integer>> triangle) {
        int rows = triangle.size();
        int[] results = new int[rows+1];

        for(int i=rows-1; i>=0; i--) {
            
            List<Integer> cols = triangle.get(i);

            for(int j=0; j<cols.size(); j++) {
                
                results[j] = Math.min(results[j], results[j+1]) + cols.get(j);
                
            }
        }
        return results[0];
    }
}