面试题(2):红包算法+百度经典题(手风琴效果)

120 阅读3分钟

红包算法

今天让我们探讨一种更贴近真实场景的红包分配方法,它能在保持一定随机性的同时,更好地控制红包金额的分布,避免极端情况出现,使分配更为公平。现在跟着我的思路来。

初始化

定义一个空数组arr来存储每个人分到的红包金额,以及两个变量:restAmount用于追踪剩余未分配的总金额(初始值为total),restNum用于追踪还有多少人未领取红包(初始值为num)。

    const arr=[]//存储每个人的红包金额
    let restAmout=total//余额
    let restNum=num//未领取人数

如何实现平均随机分配

我采用的是Math.random()结合for循环,使用for循环,从0开始到num-2结束(因为最后一个人的红包可以直接通过剩余金额确定,不需要再次随机)。

通过(restAmount/restNum*2)计算出当前理论上最大可分配金额的两倍,试图让分配金额更加随机,既有可能接近人均,也有可能略高于人均。

parseFloat().toFixed(2)用于保留两位小数。

for(let i=0;i<num-1;i++){
        let amount=parseFloat(Math.random()*(restAmout/restNum*2)).toFixed(2)
        arr[i]=amount
        restAmout-=arr[i]
        restNum--
    }
arr.push(restAmout.toFixed(2))

结果测试

假设红包金额为1元,3个人抢红包。

console.log(hongbao(1,3))

image.png

实现总代码

/*
*@func 红包算法
*@param{number}total 总金额
*@param{number}num 人数
*/ 
function hongbao(total,num){
    //发红包的那一刻就已经决定了
    //宕机
    const arr=[]
    let restAmout=total//余额
    let restNum=num//未领取人数
    for(let i=0;i<num-1;i++){
        let amount=parseFloat(Math.random()*(restAmout/restNum*2)).toFixed(2)
        arr[i]=amount
        restAmout-=arr[i]
        restNum--
    }
    arr.push(restAmout.toFixed(2))
    return arr
}

手风琴效果

首先来让我们看一看手风琴的效果

image.png

要实现这个效果,我想到的是采用ul、li

<ul class="accordion">
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
    </ul>

.accordion类应用了弹性盒子(flexbox)布局。

.accordion {
  display: flex;
  width: 600px;
  height: 200px;
}

之后设置li内部元素的布局

.accordion li {
  flex: 1;
  line-height: 200px;
  text-align: center;
  cursor: pointer;
  color: #fff;
  transition: flex 800ms;
}
  • 每个列表项(li)都被赋予了弹性盒子模型中的flex: 1,意味着它们将均匀分配容器的宽度。
  • line-height与高度相同,确保文本垂直居中。
  • text-align: center使文本水平居中。
  • cursor: pointer指示鼠标悬停时变为手型,提示用户可以点击。
  • color: #fff设置文本颜色为白色。
  • transition: flex 800msflex属性的变化添加了一个过渡效果,持续时间为800毫秒,当鼠标悬停时会平滑改变大小。

接下来分别设置了每个列表项的背景颜色,通过:nth-child()选择器指定,为每个项目提供了不同的颜色。


最后设置当鼠标悬停在列表项上时,该列表项的flex值变为2,意味着它会相对于其他未被悬停的项扩大,由于之前设置了过渡效果,这个变化会平滑进行。

.accordion li:hover {
  flex: 2;
}

完整实现代码

html部分

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>手风琴</title>
    <link rel="stylesheet" href="common.css">
</head>
<body>
    <ul class="accordion">
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
    </ul>
</body>
</html>

css部分

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
ul,
li {
  list-style-type: none;
}
.accordion {
  display: flex;
  width: 600px;
  height: 200px;
}
.accordion li {
  flex: 1;
  line-height: 200px;
  text-align: center;
  cursor: pointer;
  color: #fff;
  transition: flex 800ms;
}
.accordion li:nth-child(1) {
  background-color: #f66;
}
.accordion li:nth-child(2) {
  background-color: #66f;
}
.accordion li:nth-child(3) {
  background-color: #24b86e;
}
.accordion li:nth-child(4) {
  background-color: #b8ef1f;
}
.accordion li:nth-child(5) {
  background-color: #cf1892;
}
.accordion li:nth-child(6) {
  background-color: #0d3a4a;
}
.accordion li:hover {
  flex: 2;
}