[Leetcode Weekly Contest]287
链接:LeetCode
[Leetcode]2224. 转化时间需要的最少操作数
给你两个字符串 current 和 correct ,表示两个 24 小时制时间 。
24 小时制时间 按 "HH:MM" 进行格式化,其中 HH 在 00 和 23 之间,而 MM 在 00 和 59 之间。最早的 24 小时制时间为 00:00 ,最晚的是 23:59 。
在一步操作中,你可以将 current 这个时间增加 1、5、15 或 60 分钟。你可以执行这一操作 任意 次数。
返回将 current 转化为 correct 需要的 最少操作数 。
按分钟和小时计算即可。
class Solution {
public int convertTime(String current, String correct) {
String[] current_spilt = current.split(":"), correct_split = correct.split(":");
int diff_hour = Integer.valueOf(correct_split[0]) - Integer.valueOf(current_spilt[0]);
int diff_minute = Integer.valueOf(correct_split[1]) - Integer.valueOf(current_spilt[1]);
if(diff_minute < 0) {
diff_minute += 60;
diff_hour -= 1;
}
int diff = 60 * diff_hour + diff_minute;
return diff / 60 + diff %60 / 15 + diff % 15 / 5 + diff %5;
}
}
[Leetcode]2225. 找出输掉零场或一场比赛的玩家
给你一个整数数组 matches 其中 matches[i] = [winneri, loseri] 表示在一场比赛中 winneri 击败了 loseri 。
返回一个长度为 2 的列表 answer :
- answer[0] 是所有 没有 输掉任何比赛的玩家列表。
- answer[1] 是所有恰好输掉 一场 比赛的玩家列表。
两个列表中的值都应该按 递增 顺序返回。
注意:
- 只考虑那些参与 至少一场 比赛的玩家。
- 生成的测试用例保证 不存在 两场比赛结果 相同 。。
哈希表存储玩家输赢状态即可。
class Solution {
public List<List<Integer>> findWinners(int[][] matches) {
Set<Integer> users = new TreeSet<>();
HashMap<Integer, Integer> loserCounter = new HashMap<>();
for(int[] match: matches) {
int winner = match[0], loser = match[1];
users.add(winner);
users.add(loser);
loserCounter.put(loser, loserCounter.getOrDefault(loser, 0) + 1);
}
List<List<Integer>> res = new ArrayList<>();
List<Integer> ans1 = new ArrayList<>();
List<Integer> ans2 = new ArrayList<>();
for(var user: users) {
int loserCount = loserCounter.getOrDefault(user, 0);
if(loserCount == 0) ans1.add(user);
else if(loserCount == 1) ans2.add(user);
}
res.add(ans1);
res.add(ans2);
return res;
}
}
[Leetcode]2226. 每个小孩最多能分到多少糖果
给你一个 下标从 0 开始 的整数数组 candies 。数组中的每个元素表示大小为 candies[i] 的一堆糖果。你可以将每堆糖果分成任意数量的 子堆 ,但 无法 再将两堆合并到一起。
另给你一个整数 k 。你需要将这些糖果分配给 k 个小孩,使每个小孩分到 相同 数量的糖果。每个小孩可以拿走 至多一堆 糖果,有些糖果可能会不被分配。
返回每个小孩可以拿走的 最大糖果数目 。
二分查找转化为判定问题。需要注意越界问题,在求sum时要转换为long stream求sum,另外在check函数(即canAllocate)中可以分配的个数也要定义为long。
class Solution {
public int maximumCandies(int[] candies, long k) {
if(Arrays.stream(candies).asLongStream().sum() < k) return 0;
int lo = 1, hi = Arrays.stream(candies).max().getAsInt();
while(lo <= hi) {
int mid = lo + ((hi - lo) >> 1);
if(canAllocate(candies, k, mid)) {
lo = mid + 1;
}
else {
hi = mid - 1;
}
}
return hi;
}
public boolean canAllocate(int[] candies, long k, int target) {
long allo = 0;
for(var candy:candies) {
allo += candy / target;
if(allo >= k) return true;
}
return false;
}
}
[Leetcode]2227. 加密解密字符串
给你一个字符数组 keys ,由若干 互不相同 的字符组成。还有一个字符串数组 values ,内含若干长度为 2 的字符串。另给你一个字符串数组 dictionary ,包含解密后所有允许的原字符串。请你设计并实现一个支持加密及解密下标从 0 开始字符串的数据结构。
字符串 加密 按下述步骤进行:
- 对字符串中的每个字符 c ,先从 keys 中找出满足 keys[i] == c 的下标 i 。
- 在字符串中,用 values[i] 替换字符 c 。
字符串 解密 按下述步骤进行:
- 将字符串每相邻 2 个字符划分为一个子字符串,对于每个子字符串 s ,找出满足 values[i] == s 的一个下标 i 。如果存在多个有效的 i ,从中选择 任意 一个。这意味着一个字符串解密可能得到多个解密字符串。
- 在字符串中,用 keys[i] 替换 s 。
实现 Encrypter 类:
- Encrypter(char[] keys, String[] values, String[] dictionary) 用 keys、values 和 dictionary 初始化 Encrypter 类。
- String encrypt(String word1) 按上述加密过程完成对 word1 的加密,并返回加密后的字符串。
- int decrypt(String word2) 统计并返回可以由 word2 解密得到且出现在 dictionary 中的字符串数目。
前缀树记录字典信息。
import collections
class TreeNode:
def __init__(self):
self.children = {}
self.isValid = False
class Tree:
def __init__(self, dictionary):
self.root = TreeNode()
for word in dictionary:
self.addValue(word)
def addValue(self, word):
current = self.root
for w in word:
if w not in current.children:
current.children[w] = TreeNode()
current = current.children[w]
else:
current = current.children[w]
current.isValid = True
def findResult(self, values):
res = 0
current = [self.root]
for vs in values:
nexts = []
for v in vs:
for node in current:
if v not in node.children: continue
else: nexts.append(node.children[v])
current = nexts
for n in nexts:
if n.isValid:
res += 1
return res
class Encrypter:
def __init__(self, keys: List[str], values: List[str], dictionary: List[str]):
self.key_value = {}
self.value_key = collections.defaultdict(list)
for i in range(len(keys)):
key, value = keys[i], values[i]
self.key_value[key] = value
self.value_key[value].append(key)
self.root = Tree(dictionary)
def encrypt(self, word1: str) -> str:
res = ''
for w in word1:
res += self.key_value[w]
return res
def decrypt(self, word2: str) -> int:
values = []
for i in range(0, len(word2), 2):
value = word2[i: i+2]
if value not in self.value_key: return 0
else: values.append(self.value_key[value])
return self.root.findResult(values)
# Your Encrypter object will be instantiated and called as such:
# obj = Encrypter(keys, values, dictionary)
# param_1 = obj.encrypt(word1)
# param_2 = obj.decrypt(word2)