/*
难度:中等
大餐是指恰好包含两道不同餐品的一餐,其美味程度之和等于2的幂。
你可以搭配任意两道餐品做一顿大餐。
给定一个整数数组,其中第i项是第i道餐品的美味程度,返回你可以用数组中的餐品做出的不同大餐的数量。
结果需要对 10^9 + 7 取余。
只要餐品下标不同就可以认为是不同的餐品,即便美味程度相同。
示例 1:
输入:deliciousness=[1,3,5,7,9]
输出:4
解释:(1,3), (1,7),(3,5),(7,9)
示例 2:
输入:deliciousness=[1,1,1,3,3,3,7]
输出:15
解释:3种(1,1), 9种(1,3), 3种(1,7)
提示:
1<= deliciousness.length <= 100000
0<= deliciousness[i] <= 2^20
*/
extension Daily {
static func test_leetcode1711() {
let cases = [
[1,3,5,7,9],
[1,1,1,3,3,3,7],
[1048576,1048576],
]
for deliciousness in cases {
print("输入:\(deliciousness)")
let start = NSDate.now
print("开始时间 \(NSDate.now)")
let res = Daily.leetcode1711(deliciousness: deliciousness)
let end = NSDate.now
print("输出:\(res), \(end.timeIntervalSince(start))\n")
}
}
static func leetcode1711(deliciousness: [Int]) -> Int {
//必须包含两道餐品
if deliciousness.count < 2 {
return 0
}
var stat = [Int:Int]()
for idx in 0..<deliciousness.count {
let current = deliciousness[idx]
if stat[current] == nil {
stat[current] = 1
}
else {
stat[current]! += 1
}
}
let bits = [
0x200000, 0x100000, 0x80000, 0x40000, 0x20000,
0x10000, 0x8000, 0x4000, 0x2000, 0x1000,
0x800, 0x400, 0x200, 0x100, 0x80,
64, 32, 16, 8, 4, 2, 1,
]
var total = 0
for idx in 0..<deliciousness.count {
let current = deliciousness[idx]
if stat[current] == nil {
continue
}
for other in bits {
if other < current {
break
}
let rest = other - current
if let x = stat[rest] {
if rest == current {
total += x*(x-1)/2
}
else {
total += x * stat[current]!
}
}
}
total %= 1000000007
stat.removeValue(forKey: current)
}
return total
}
}
【LeetCode 1711】大餐计数
最新推荐文章于 2021-12-30 11:20:02 发布