目录
日志排序
考察排序。
题目描述
运维工程师采集到某产品现网运行一天产生的日志N条,现需根据日志时间按时间先后顺序对日志进行排序。
日志时间格式为:
H:M:S.N
H表示小时(0-23),M表示分钟(0-59),S表示秒(0-59),N表示毫秒(0-999)
时间可能并没有补齐,也就是说:01:01:01.001,也可能表示为1:1:1.1,
输入描述
第一行输入一个整数N,表示日志条数,1<=N<=100000
接下来N行输入N个时间
输出描述
按时间升序排序之后的时间
如果有两个时间表示的时间相同,则保持输入顺序
示例1
输入
2
01:41:8.9
1:1:09.211
输出
1:1:09.211
01:41:8.9
示例2
输入
3
23:41:08.023
1:1:09.211
08:01:22.0
输出
1:1:09.211
08:01:22.0
23:41:08.023
示例3
输入
2
22:41:08.023
22:41:08.23
输出
22:41:08.023
22:41:08.23
说明
两个时间表示的时间相同,保持输入顺序
解析
答案
// 不需要以':'分隔后每个比较
// 注意相等的情况是不需要换位置的
function logSort(n, ...logs) {
logs = logs.map(v => ({
v,
number: v.split(':').map((value, index) => {
return value * Math.pow(10, 3 * (3 - index))
}).reduce((t, v) => t + v)
}))
logs.sort((a, b) => a.number - b.number)
return logs.map(v => v.v)
}
console.log(logSort(2, '01:41:8.9', '1:1:09.211'))
console.log(logSort(3, '23:41:08.023', '1:1:09.211', '08:01:22.0'))
console.log(logSort(2, '22:41:08.023', '22:41:08.23'))
最长的顺子
考察hash算法和转化思想。
题目描述
斗地主Q起源于湖北十堰房县,据说是—位叫吴修全的年轻人根据当地流行的扑克玩法"跑得快"改编的,如今已风靡整个中国,并流行于 互联网上。
牌型:单顺,又称顺子,最少5张牌,最多12张牌(3...A)不能有2,也不能有大小王,不计花色。 例如:3-4-5-6-7-8,7-8-9-10-J-Q,3-4-5-6-7-8-9-10-J-Q-K-A 可用的牌 3<4<5<6<7<89<10<j<Q<K<A<2<B(小王)<C(大王),每种牌除大小王外有四种花色 (共有13x4+2张牌)
输入: 1.手上有的牌 2.已经出过的牌(包括对手出的和自己出的牌)
输出: 对手可能构成的最长的顺子(如果有相同长度的顺子,输出牌面最大的那一个),如果无法构成顺子,则输出 NO-CHAIN。
输入描述
输入的第一行为当前手中的牌
输入的第二行为已经出过的牌
输出描述
最长的顺子
示例1
输入
3-3-3-3-4-4-5-5-6-7-8-9-10-J-Q-K-A
4-5-6-7-8-8-8
输出
9-10-J-Q-K-A
示例2
输入
3-3-3-3-8-8-8-8
K-K-K-K
输出
NO-CHAIN
说明
剩余的牌无法构成顺子
解析
答案
// 需要处理到不参与顺子的牌2,B,C
function longSequence(myCard, useCard) {
let obj = {}
let noUse = []
let hash = {
3: 3,
4: 4,
5: 5,
6: 6,
7: 7,
8: 8,
9: 9,
10: 10,
'J': 11,
'Q': 12,
'K': 13,
'A': 14,
11: 'J',
12: 'Q',
13: 'K',
14: 'A',
}
let tmp = [...myCard.split('-'), ...useCard.split('-')].forEach(v => {
v = hash[v]
if (!v) {
return
}
if (obj[v]) {
obj[v]++
if (obj[v] === 4) {
noUse.push(v)
}
} else {
obj[v] = 1
}
})
noUse.sort((a, b) => a - b)
let sequences = []
for (let i = -1, j = i + 1; i < noUse.length; i++, j++) {
let start = i === -1 ? 2 : noUse[i] //start表示用完了,所以这里要写3-1
let end = j === noUse.length ? 15 : noUse[j] //end表示用完了,所以这里要写14+1
if (end - start > 5) {
sequences.push([start + 1, end - 1])
}
}
if (!sequences.length) {
return 'NO-CHAIN'
}
// 上面是按从小到大的顺序取的顺子,所以这里只用对长度进行小到大排序取最后一个
let res = sequences.sort((a, b) => (a[1] - a[0]) - (b[1] - b[0])).pop()
tmp = []
for (let i = res[0]; i <= res[1]; i++) {
tmp.push(hash[i])
}
return tmp.join('-')
}
console.log(longSequence('3-3-3-3-4-4-5-5-6-7-8-9-10-J-Q-K-A', '4-5-6-7-8-8-8'))
console.log(longSequence('3-3-3-3-8-8-8-8', 'K-K-K-K'))
求最多可以派出多少支团队
考察双指针
题目描述
用数组代表每个人的能力,一个比赛活动要求参赛团队的最低能力值为N,每个团队可以由1人或2人组成,且1个人只能参加1个团队,请计算出最多可以派出多少支符合要求的团队?
输入描述
5
3 1 5 7 9
8
第一行数组代表总人数,范围[1,500000]
第二行数组代表每个人的能力,每个元素的取值范围[1,500000],数组的大小范围[1,500000] 第三行数值为团队要求的最低能力值,范围[1,500000]
输出描述
最多可以派出的团队数量
说明
3,5组成一队,1,7组成一队,9自己一个队,故输出3
解析
答案
// 求最多可以派出多少支团队
function maxGroup(num, groups, min) {
let sum = groups.filter(v => v >= min).length
groups = groups.filter(v => v < min).sort((a, b) => a - b)
let i = 0, j = groups.length - 1
while (i < j) {
if (groups[j] + groups[i] >= min) {
sum++
j--
i++
} else {
i++
}
}
return sum
}
console.log(maxGroup(5, [3, 1, 5, 7, 9], 8))