[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 开始字符串的数据结构。
字符串 加密 按下述步骤进行:

  1. 对字符串中的每个字符 c ,先从 keys 中找出满足 keys[i] == c 的下标 i 。
  2. 在字符串中,用 values[i] 替换字符 c 。

字符串 解密 按下述步骤进行:

  1. 将字符串每相邻 2 个字符划分为一个子字符串,对于每个子字符串 s ,找出满足 values[i] == s 的一个下标 i 。如果存在多个有效的 i ,从中选择 任意 一个。这意味着一个字符串解密可能得到多个解密字符串。
  2. 在字符串中,用 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)
posted @ 2022-05-26 20:04  Jamest  阅读(23)  评论(0编辑  收藏  举报