Manjusaka

Manjusaka

Leetcode Weekly Contest 287 Problem Solutions

It's been a while since I participated in a weekly contest, so I decided to write a simple solution.

2224. Minimum Number of Operations to Convert Time#

Problem Statement:

You are given two strings current and correct representing two 24-hour times.

24-hour times are formatted as "HH:MM", where HH is between 00 and 23, and MM is between 00 and 59. The earliest 24-hour time is 00:00, and the latest is 23:59.

In one operation you can increase the time current by 1, 5, 15, or 60 minutes. You can perform this operation any number of times.

Return the minimum number of operations needed to convert current to correct.

Example:

 
Example 1:

Input: current = "02:30", correct = "04:35"
Output: 3
Explanation:
We can convert current to correct in 3 operations as follows:
- Add 60 minutes to current. current becomes "03:30".
- Add 60 minutes to current. current becomes "04:30".
- Add 5 minutes to current. current becomes "04:35".
It can be proven that it is not possible to convert current to correct in fewer than 3 operations.

Example 2:

Input: current = "11:00", correct = "11:01"
Output: 1
Explanation: We only have to add one minute to current, so the minimum number of operations needed is 1.

There's not much to say about this problem; just calculate the time directly.

class Solution:
    def convertTime(self, current: str, correct: str) -> int:
        correct_time = correct.split(':')
        current_time = current.split(':')
        minutes = int(correct_time[1]) - int(current_time[1])
        hours = int(correct_time[0]) - int(current_time[0])
        if correct_time[1] < current_time[1]:
            minutes += 60
            hours -= 1
        results = hours
        flag = [15, 5, 1]
        for i in flag:
            if minutes >= i:
                results += (minutes // i)
                minutes = minutes % i
        return results

2225. Find Players With Zero or One Losses#

Problem Statement:

You are given an integer array matches where matches[i] = [winneri, loseri] indicates that the player winneri defeated player loseri in a match.

Return a list answer of size 2 where:

answer[0] is a list of all players that have not lost any matches.
answer[1] is a list of all players that have lost exactly one match.
The values in the two lists should be returned in increasing order.

Note:

You should only consider the players that have played at least one match.
The testcases will be generated such that no two matches will have the same outcome.

Example:

Example 1:

Input: matches = [[1,3],[2,3],[3,6],[5,6],[5,7],[4,5],[4,8],[4,9],[10,4],[10,9]]
Output: [[1,2,10],[4,5,7,8]]
Explanation:
Players 1, 2, and 10 have not lost any matches.
Players 4, 5, 7, and 8 each have lost one match.
Players 3, 6, and 9 each have lost two matches.
Thus, answer[0] = [1,2,10] and answer[1] = [4,5,7,8].


Example 2:

Input: matches = [[2,3],[1,3],[5,4],[6,4]]
Output: [[1,2,5,6],[]]
Explanation:
Players 1, 2, 5, and 6 have not lost any matches.
Players 3 and 4 each have lost two matches.
Thus, answer[0] = [1,2,5,6] and answer[1] = [].

This problem can actually be solved by traversing and counting, with a time complexity of O(N) and space complexity of O(N).

from collections import defaultdict
from typing import List


class Solution:
    def findWinners(self, matches: List[List[int]]) -> List[List[int]]:
        index = defaultdict(lambda: [0, 0])
        for winner, loser in matches:
            index[winner][0] += 1
            index[loser][1] += 1
        return [
            sorted([k for k, v in index.items() if v[0] > 0 and v[1] == 0]),
            sorted([k for k, v in index.items() if v[1] == 1]),
        ]

2226. Maximum Candies Allocated to K Children#

Wow, the problem number for this one is quite interesting, respect...

Problem Statement:


You are given a 0-indexed integer array candies. Each element in the array denotes a pile of candies of size candies[i]. You can divide each pile into any number of sub piles, but you cannot merge two piles together.

You are also given an integer k. You should allocate piles of candies to k children such that each child gets the same number of candies. Each child can take at most one pile of candies and some piles of candies may go unused.

Return the maximum number of candies each child can get.

Example:

Example 1:

Input: candies = [5,8,6], k = 3
Output: 5
Explanation: We can divide candies[1] into 2 piles of size 5 and 3, and candies[2] into 2 piles of size 5 and 1. We now have five piles of candies of sizes 5, 5, 3, 5, and 1. We can allocate the 3 piles of size 5 to 3 children. It can be proven that each child cannot receive more than 5 candies.

Example 2:

Input: candies = [2,5], k = 11
Output: 0
Explanation: There are 11 children but only 7 candies in total, so it is impossible to ensure each child receives at least one candy. Thus, each child gets no candy and the answer is 0.

Initially, I didn't think this problem through clearly, but after some careful consideration, it actually involves binary search.

First, let's assume the total number of candies is y, and the value when divided by k is z (meaning the maximum integer that can be divided). The range of the maximum number of candies each child can receive is definitely [0, z].

This interval is monotonic (monotonically increasing), which gives us the condition for binary search. So what is our binary search problem? Assuming the middle value is mid, we calculate how many portions we can divide the candies into according to mid and sum them up. If the sum is less than k, it means the value is greater than our target; otherwise, it is less than the target. We continue to narrow it down.

from typing import List


class Solution:
    def maximumCandies(self, candies: List[int], k: int) -> int:
        left, right = 0, sum(candies) // k
        while left < right:
            mid = (left + right + 1) // 2
            if k > sum(candy // mid for candy in candies):
                right = mid - 1
            else:
                left = mid
        return left

2227. Encrypt and Decrypt Strings#

This problem is actually simpler than the third one.

Problem Statement:

You are given a character array keys containing unique characters and a string array values containing strings of length 2. You are also given another string array dictionary that contains all permitted original strings after decryption. You should implement a data structure that can encrypt or decrypt a 0-indexed string.

A string is encrypted with the following process:

For each character c in the string, we find the index i satisfying keys[i] == c in keys.
Replace c with values[i] in the string.
A string is decrypted with the following process:

For each substring s of length 2 occurring at an even index in the string, we find an i such that values[i] == s. If there are multiple valid i, we choose any one of them. This means a string could have multiple possible strings it can decrypt to.
Replace s with keys[i] in the string.
Implement the Encrypter class:

Encrypter(char[] keys, String[] values, String[] dictionary) Initializes the Encrypter class with keys, values, and dictionary.
String encrypt(String word1) Encrypts word1 with the encryption process described above and returns the encrypted string.
int decrypt(String word2) Returns the number of possible strings word2 could decrypt to that also appear in dictionary.

Example:

Input
["Encrypter", "encrypt", "decrypt"]
[[['a', 'b', 'c', 'd'], ["ei", "zf", "ei", "am"], ["abcd", "acbd", "adbc", "badc", "dacb", "cadb", "cbda", "abad"]], ["abcd"], ["eizfeiam"]]
Output
[null, "eizfeiam", 2]

Explanation
Encrypter encrypter = new Encrypter([['a', 'b', 'c', 'd'], ["ei", "zf", "ei", "am"], ["abcd", "acbd", "adbc", "badc", "dacb", "cadb", "cbda", "abad"]);
encrypter.encrypt("abcd"); // return "eizfeiam". 
                           // 'a' maps to "ei", 'b' maps to "zf", 'c' maps to "ei", and 'd' maps to "am".
encrypter.decrypt("eizfeiam"); // return 2. 
                              // "ei" can map to 'a' or 'c', "zf" maps to 'b', and "am" maps to 'd'. 
                              // Thus, the possible strings after decryption are "abad", "cbad", "abcd", and "cbcd". 
                              // 2 of those strings, "abad" and "abcd", appear in dictionary, so the answer is 2.

For the encryption part, you can simply follow the rules to implement it, and for the decryption part, one method is to precompute the values in the dictionary, allowing for O(1) calculations.

from collections import Counter
from typing import List


class Encrypter:
    def __init__(self, keys: List[str], values: List[str], dictionary: List[str]):
        self.index = {k: v for k, v in zip(keys, values)}
        self.counter = Counter(self.encrypt(item) for item in dictionary)

    def encrypt(self, word1: str) -> str:
        return "".join(self.index.get(letter, " ") for letter in word1)

    def decrypt(self, word2: str) -> int:
        return self.counter[word2]

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.