前端面试八股
发现了一个地方包含了很多前端面试八股
1.用户喜好
为了不断优化推荐效果,今日头条每天要存储和处理海量数据。假设有这样一种场景:我们对用户按照它们的注册时间先后来标号,对于一类文章,每个用户都有不同的喜好值,我们会想知道某一段时间内注册的用户(标号相连的一批用户)中,有多少用户对这类文章喜好值为k。因为一些特殊的原因,不会出现一个查询的用户区间完全覆盖另一个查询的用户区间(不存在L1<=L2<=R2<=R1)。
时间限制:C/C++ 3秒,其他语言6秒
空间限制:C/C++ 256M,其他语言512M
输入描述:
输入: 第1行为n代表用户的个数 第2行为n个整数,第i个代表用户标号为i的用户对某类文章的喜好度 第3行为一个正整数q代表查询的组数 第4行到第(3+q)行,每行包含3个整数l,r,k代表一组查询,即标号为l<=i<=r的用户中对这类文章喜好值为k的用户的个数。 数据范围n <= 300000,q<=300000 k是整型
输出描述:
输出:一共q行,每行一个整数代表喜好值为k的用户的个数
import sys
import bisect
lines = []
for line in sys.stdin:
lines += [int(i) for i in line.strip().split(' ')]
N = lines[0]
queryN = lines[1+N]
preferences = lines[1:(1+N)]
map = {}
def insertSort(arr, i):
index = bisect.bisect(arr, i)
arr.insert(index, i)
for i, p in enumerate(preferences):
if p in map:
map[p].append(i)
else:
map[p] = [i]
for qi in range(queryN):
ql, qr, qv = lines[N+2+qi*3], lines[N+3+qi*3], lines[N+4+qi*3]
if qv not in map or len(map[qv]) == 0:
print(0)
else:
qpreference = map[qv]
il = bisect.bisect_left(qpreference, ql-1)
ir = bisect.bisect_right(qpreference, qr-1)
print(ir-il)
2.手串
作为一个手串艺人,有金主向你订购了一条包含n个杂色串珠的手串——每个串珠要么无色,要么涂了若干种颜色。为了使手串的色彩看起来不那么单调,金主要求,手串上的任意一种颜色(不包含无色),在任意连续的m个串珠里至多出现一次(注意这里手串是一个环形)。手串上的颜色一共有c种。现在按顺时针序告诉你n个串珠的手串上,每个串珠用所包含的颜色分别有哪些。请你判断该手串上有多少种颜色不符合要求。即询问有多少种颜色在任意连续m个串珠中出现了至少两次。
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 64M,其他语言128M
输入描述:
第一行输入n,m,c三个数,用空格隔开。(1 <= n <= 10000, 1 <= m <= 1000, 1 <= c <= 50) 接下来n行每行的第一个数num_i(0 <= num_i <= c)表示第i颗珠子有多少种颜色。接下来依次读入num_i个数字,每个数字x表示第i颗柱子上包含第x种颜色(1 <= x <= c)
输出描述:
一个非负整数,表示该手链上有多少种颜色不符需求。
import sys
lines = []
for line in sys.stdin:
lines += [int(i) for i in line.strip().split(' ')]
N, m, c = lines[:3]
colormap = [[False]*c for i in range(N)]
n, i = 0, 3
while i<len(lines):
n_c = lines[i]
for j in range(n_c):
colormap[n][lines[i+j+1]-1] = True
i += n_c + 1
n += 1
index_errors = list(range(c))
n_error = 0
sums = [0]*c
for i in range(m):
for j in range(c):
sums[j] += colormap[i][j]
for i in range(N):
tmp_errors = []
for j in index_errors:
if sums[j]>1:
n_error += 1
else:
tmp_errors.append(j)
index_errors = tmp_errors
for j in index_errors:
sums[j] += colormap[(i+m)%N][j] - colormap[i][j]
print(n_error)
3.TODO List
页面结构如下图所示,要求:
使用HTML与CSS完成界面开发
实现添加功能:输入框中可输入任意字符,按回车后将输入字符串添加到下方列表的最后,并清空输入框
实现删除功能:点击列表项后面的“X”号,可以删除该项
实现模糊匹配:在输入框中输入字符后,将当前输入字符串与已添加的列表项进行模糊匹配,将匹配到的结果显示在输入框下方。如匹配不到任何列表项,列表显示空
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>TODO List</title>
<style>
.header {
display: flex;
justify-content: center;
}
.main {
display: flex;
justify-content: center;
}
.logo {
font-size: 10rem;
font-weight: lighter;
color: rgb(233, 159, 202);
}
.panel {
display: flex;
flex-direction: column;
justify-content: center;
width: 40%;
box-shadow: 0 0.2em 0.2em rgba(0, 0, 0, 0.15);
}
.row,.history {
display: flex;
flex-direction: row;
width: 100%;
height: 3rem;
border-bottom: 1px solid #000;
}
.input {
display: block;
width: 100%;
height: 100%;
font-size: 1.2rem;
box-sizing:border-box;
outline-style: none;
}
.history p {
width: 95%;
font-size: 1.2rem;
}
.history span{
width: 5%;
text-align: center;
font-size: 1.2rem;
}
</style>
</head>
<body>
<div id="app">
<div class="header">
<div class="logo">todos</div>
</div>
<div class="main">
<div class="panel" id="panel">
<div class="row"><input id="addInput"" class="input"></input></div>
</div>
</div>
</div>
<script>
var store = []
var addInput = document.getElementById("addInput");
var panel = document.getElementById("panel");
addInput.onkeyup = function() {
if (event.keyCode == '13'){
newStr = addInput.value;
let flag = false;
for(let i =0;i<store.length; i++){
if(store[i]==newStr){
flag = true;
}
}
if(!flag){
store.push(newStr);
var oDiv = document.createElement('div');
var oSpan = document.createElement('span');
var oP = document.createElement('p');
oDiv.appendChild(oP);
oDiv.appendChild(oSpan);
oP.innerHTML = newStr;
oSpan.innerHTML = '×';
oDiv.className = "history";
oSpan.onclick = function() {
console.log(store);
for(let i =0;i<store.length; i++){
if(store[i]==newStr){
store.splice(i,1);
break;
}
}
this.parentNode.remove();
}
panel.appendChild(oDiv);
}
addInput.value = "";
}
var str = addInput.value;
var reg = new RegExp('('+str+')', 'g');
var all = document.getElementsByClassName('history');
if(str == ''){
for( let i = 0; i<all.length; i++ ){
all[i].getElementsByTagName('p')[0].innerHTML = store[i];
all[i].style.display = 'flex';//输入框空时全部显示
}
return;
}
for(let i=0; i<all.length; i++){
if (store[i].indexOf(str)==-1){
all[i].style.display = 'none';
all[i].getElementsByTagName('p')[0].innerHTML = store[i];
}else{
var newStr = store[i].replace(reg, '<font color=red>$1</font>');//换-->红色,用innerText防止用innerHTML将标签也读取出来出错。
let h_str = all[i].getElementsByTagName('p')[0];
console.log('test:'+all[i].innerHTML)
h_str.innerHTML = newStr;
}
}
}
</script>
</body>
</html>
4.
有n个房间,现在i号房间里的人需要被重新分配,分配的规则是这样的:先让i号房间里的人全都出来,接下来按照 i+1, i+2, i+3, … 的顺序依此往这些房间里放一个人,n号房间的的下一个房间是1号房间,直到所有的人都被重新分配。
现在告诉你分配完后每个房间的人数以及最后一个人被分配的房间号x,你需要求出分配前每个房间的人数。数据保证一定有解,若有多解输出任意一个解。
输入描述:
第一行两个整数n, x (2<=n<=10^5, 1<=x<=n),代表房间房间数量以及最后一个人被分配的房间号;
第二行n个整数 a_i(0<=a_i<=10^9) ,代表每个房间分配后的人数。
输出描述:
输出n个整数,代表每个房间分配前的人数。
import sys
lines = []
for line in sys.stdin:
lines.append(line.strip())
n, x = [int(i) for i in lines[0].split(' ')]
counts = [int(i) for i in lines[1].split(' ')]
x -= 1
minIndex = x
for i in range(0, n):
if counts[(x-i)%n]<counts[minIndex]:
minIndex = (x-i)%n
if minIndex<=x:
for i in range(x+1, n+minIndex):
counts[i%n] -= counts[minIndex]
for i in range(minIndex+1, x+1):
counts[i] -= 1 + counts[minIndex]
counts[minIndex] = x-minIndex + counts[minIndex]*n
else:
for i in range(x+1, minIndex):
counts[i] -= counts[minIndex]
for i in range(minIndex+1, x+n+1):
counts[i%n] -= 1+ counts[minIndex]
counts[minIndex] = n+x-minIndex + counts[minIndex]*n
# print(minIndex, x)
print(' '.join([str(i) for i in counts]))