1. 程式人生 > 其它 >[Leetcode Weekly Contest]287

[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)