diff --git a/solution/0800-0899/0805.Split Array With Same Average/README.md b/solution/0800-0899/0805.Split Array With Same Average/README.md index 490c1b2e655a1..a6d828aff535a 100644 --- a/solution/0800-0899/0805.Split Array With Same Average/README.md +++ b/solution/0800-0899/0805.Split Array With Same Average/README.md @@ -62,9 +62,9 @@ tags: ### 方法一:折半查找 + 二进制枚举 -根据题目要求,要判断是否可以将数组 `nums` 划分为两个子数组 $A$ 和 $B$,使得两个子数组的平均值相等。 +根据题目要求,要判断是否可以将数组 $\textit{nums}$ 划分为两个子数组 $A$ 和 $B$,使得两个子数组的平均值相等。 -我们记数组 `nums` 的和为 $s$,元素个数为 $n$。子数组 $A$ 的和以及个数分别为 $s_1$ 和 $k$,那么子数组 $B$ 的和为 $s_2 = s - s_1$,个数为 $n - k$,即: +我们记数组 $\textit{nums}$ 的和为 $s$,元素个数为 $n$。子数组 $A$ 的和以及个数分别为 $s_1$ 和 $k$,那么子数组 $B$ 的和为 $s_2 = s - s_1$,个数为 $n - k$,即: $$ \frac{s_1}{k} = \frac{s_2}{n - k} = \frac{s-s_1}{n-k} @@ -82,25 +82,25 @@ $$ \frac{s_1}{k} = \frac{s}{n} $$ -也就是说,要我们找出一个子数组 $A$,使得其平均值等于数组 `nums` 的平均值。我们考虑将数组 `nums` 每个元素都减去数组 `nums` 的平均值,这样问题就转化为了在数组 `nums` 中找出一个子数组,使得其和为 $0$。 +也就是说,要我们找出一个子数组 $A$,使得其平均值等于数组 $\textit{nums}$ 的平均值。我们考虑将数组 $\textit{nums}$ 每个元素都减去数组 $\textit{nums}$ 的平均值,这样问题就转化为了在数组 $\textit{nums}$ 中找出一个子数组,使得其和为 $0$。 -但是,数组 `nums` 的平均值可能不是整数,浮点数计算可能存在精度问题,我们不妨将数组 `nums` 中的每个元素都乘以 $n$,即 $nums[i] \leftarrow nums[i] \times n$,上述式子就变成: +但是,数组 $\textit{nums}$ 的平均值可能不是整数,浮点数计算可能存在精度问题,我们不妨将数组 $\textit{nums}$ 中的每个元素都乘以 $n$,即 $nums[i] \leftarrow nums[i] \times n$,上述式子就变成: $$ \frac{s_1\times n}{k} = s $$ -此时我们将数组 `nums` 中每个元素都减去整数 $s$,题目就转化为:在数组 $nums$ 中找出一个子数组 $A$,使得其和为 $0$。 +此时我们将数组 $\textit{nums}$ 中每个元素都减去整数 $s$,题目就转化为:在数组 $nums$ 中找出一个子数组 $A$,使得其和为 $0$。 -数组 `nums` 的长度范围为 $[1, 30]$,如果我们使用暴力枚举子数组的方法,时间复杂度为 $O(2^n)$,会超时。我们可以使用折半查找的方法,将时间复杂度降低到 $O(2^{n/2})$。 +数组 $\textit{nums}$ 的长度范围为 $[1, 30]$,如果我们使用暴力枚举子数组的方法,时间复杂度为 $O(2^n)$,会超时。我们可以使用折半查找的方法,将时间复杂度降低到 $O(2^{n/2})$。 -我们将数组 `nums` 分成左右两部分,那么子数组 $A$ 可能存在三种情况: +我们将数组 $\textit{nums}$ 分成左右两部分,那么子数组 $A$ 可能存在三种情况: -1. 子数组 $A$ 完全在数组 `nums` 的左半部分; -2. 子数组 $A$ 完全在数组 `nums` 的右半部分; -3. 子数组 $A$ 一部分在数组 `nums` 的左半部分,一部分在数组 `nums` 的右半部分。 +1. 子数组 $A$ 完全在数组 $\textit{nums}$ 的左半部分; +2. 子数组 $A$ 完全在数组 $\textit{nums}$ 的右半部分; +3. 子数组 $A$ 一部分在数组 $\textit{nums}$ 的左半部分,一部分在数组 $\textit{nums}$ 的右半部分。 -我们可以使用二进制枚举的方法,先枚举左半部分所有子数组的和,如果存在一个子数组和为 $0$,直接返回 `true`,否则我们将其存入哈希表 `vis` 中;然后枚举右半部分所有子数组的和,如果存在一个子数组和为 $0$,直接返回 `true`,否则我们判断此时哈希表 `vis` 中是否存在该和的相反数,如果存在,直接返回 `true`。 +我们可以使用二进制枚举的方法,先枚举左半部分所有子数组的和,如果存在一个子数组和为 $0$,直接返回 `true`,否则我们将其存入哈希表 $\textit{vis}$ 中;然后枚举右半部分所有子数组的和,如果存在一个子数组和为 $0$,直接返回 `true`,否则我们判断此时哈希表 $\textit{vis}$ 中是否存在该和的相反数,如果存在,直接返回 `true`。 需要注意的是,我们不能同时全选左半部分和右半部分,因为这样会导致子数组 $B$ 为空,这是不符合题意的。在实现上,我们只需要考虑数组的 $n-1$ 个数。 diff --git a/solution/0800-0899/0805.Split Array With Same Average/README_EN.md b/solution/0800-0899/0805.Split Array With Same Average/README_EN.md index 4c18f31072a5e..2240b468056ef 100644 --- a/solution/0800-0899/0805.Split Array With Same Average/README_EN.md +++ b/solution/0800-0899/0805.Split Array With Same Average/README_EN.md @@ -58,7 +58,51 @@ tags: -### Solution 1 +### Solution 1: Binary Search + Binary Enumeration + +According to the problem requirements, we need to determine if the array $\textit{nums}$ can be divided into two subarrays $A$ and $B$ such that the average values of the two subarrays are equal. + +Let the sum of the array $\textit{nums}$ be $s$, and the number of elements be $n$. The sum and number of elements of subarray $A$ are $s_1$ and $k$, respectively. Then the sum of subarray $B$ is $s_2 = s - s_1$, and the number of elements is $n - k$. Thus: + +$$ +\frac{s_1}{k} = \frac{s_2}{n - k} = \frac{s-s_1}{n-k} +$$ + +Rearranging, we get: + +$$ +s_1 \times (n-k) = (s-s_1) \times k +$$ + +Simplifying, we get: + +$$ +\frac{s_1}{k} = \frac{s}{n} +$$ + +This means we need to find a subarray $A$ such that its average value equals the average value of the array $\textit{nums}$. We consider subtracting the average value of the array $\textit{nums}$ from each element of the array $\textit{nums}$, transforming the problem into finding a subarray in the array $\textit{nums}$ whose sum is $0$. + +However, the average value of the array $\textit{nums}$ may not be an integer, and floating-point calculations may have precision issues. We can multiply each element of the array $\textit{nums}$ by $n$, i.e., $nums[i] \leftarrow nums[i] \times n$. The above equation becomes: + +$$ +\frac{s_1\times n}{k} = s +$$ + +Now, we subtract the integer $s$ from each element of the array $\textit{nums}$, transforming the problem into finding a subarray $A$ in the array $nums$ whose sum is $0$. + +The length of the array $\textit{nums}$ ranges from $[1, 30]$. If we use brute force to enumerate subarrays, the time complexity is $O(2^n)$, which will time out. We can use binary search to reduce the time complexity to $O(2^{n/2})$. + +We divide the array $\textit{nums}$ into left and right parts. The subarray $A$ can exist in three cases: + +1. Subarray $A$ is entirely in the left part of the array $\textit{nums}$; +2. Subarray $A$ is entirely in the right part of the array $\textit{nums}$; +3. Subarray $A$ is partially in the left part and partially in the right part of the array $\textit{nums}$. + +We can use binary enumeration to first enumerate the sums of all subarrays in the left part. If there is a subarray with a sum of $0$, we return `true` immediately. Otherwise, we store the sums in a hash table $\textit{vis}$. Then we enumerate the sums of all subarrays in the right part. If there is a subarray with a sum of $0$, we return `true` immediately. Otherwise, we check if the hash table $\textit{vis}$ contains the opposite of the current sum. If it does, we return `true`. + +Note that we cannot select all elements from both the left and right parts simultaneously, as this would leave subarray $B$ empty, which does not meet the problem requirements. In implementation, we only need to consider $n-1$ elements of the array. + +The time complexity is $O(n \times 2^{\frac{n}{2}})$, and the space complexity is $O(2^{\frac{n}{2}})$. diff --git a/solution/0800-0899/0808.Soup Servings/README_EN.md b/solution/0800-0899/0808.Soup Servings/README_EN.md index 5c3e112d589c3..46661ed7c7bef 100644 --- a/solution/0800-0899/0808.Soup Servings/README_EN.md +++ b/solution/0800-0899/0808.Soup Servings/README_EN.md @@ -65,7 +65,32 @@ So the total probability of A becoming empty first plus half the probability tha -### Solution 1 +### Solution 1: Memoization Search + +In this problem, since each operation is a multiple of $25$, we can consider every $25ml$ of soup as one unit. This reduces the data scale to $\left \lceil \frac{n}{25} \right \rceil$. + +We design a function $dfs(i, j)$, which represents the probability result when there are $i$ units of soup $A$ and $j$ units of soup $B$ remaining. + +When $i \leq 0$ and $j \leq 0$, it means both soups are finished, and we should return $0.5$. When $i \leq 0$, it means soup $A$ is finished first, and we should return $1$. When $j \leq 0$, it means soup $B$ is finished first, and we should return $0$. + +Next, for each operation, we have four choices: + +- Take $4$ units from soup $A$ and $0$ units from soup $B$; +- Take $3$ units from soup $A$ and $1$ unit from soup $B$; +- Take $2$ units from soup $A$ and $2$ units from soup $B$; +- Take $1$ unit from soup $A$ and $3$ units from soup $B$. + +Each choice has a probability of $0.25$, so we can derive: + +$$ +dfs(i, j) = 0.25 \times (dfs(i - 4, j) + dfs(i - 3, j - 1) + dfs(i - 2, j - 2) + dfs(i - 1, j - 3)) +$$ + +We use memoization to store the results of the function. + +Additionally, we find that when $n=4800$, the result is $0.999994994426$, and the required precision is $10^{-5}$. As $n$ increases, the result gets closer to $1$. Therefore, when $n \gt 4800$, we can directly return $1$. + +The time complexity is $O(C^2)$, and the space complexity is $O(C^2)$. In this problem, $C=200$. diff --git a/solution/0800-0899/0809.Expressive Words/README.md b/solution/0800-0899/0809.Expressive Words/README.md index f08d616e8e960..5da82058abe75 100644 --- a/solution/0800-0899/0809.Expressive Words/README.md +++ b/solution/0800-0899/0809.Expressive Words/README.md @@ -31,7 +31,7 @@ tags:
示例:
-输入: +输入: s = "heeellooo" words = ["hello", "hi", "helo"] 输出:1 @@ -58,17 +58,17 @@ words = ["hello", "hi", "helo"] ### 方法一:遍历计数 + 双指针 -我们可以遍历数组 `words`,对于数组中的每个单词 $t$,判断 $t$ 是否可以通过扩张得到 $s$,如果可以,那么答案加一。 +我们可以遍历数组 $\textit{words}$,对于数组中的每个单词 $t$,判断 $t$ 是否可以通过扩张得到 $s$,如果可以,那么答案加一。 -因此,问题的关键在于判断单词 $t$ 是否可以通过扩张得到 $s$。这里我们通过一个 $check(s, t)$ 函数来判断。函数的具体实现逻辑如下: +因此,问题的关键在于判断单词 $t$ 是否可以通过扩张得到 $s$。这里我们通过一个 $\textit{check}(s, t)$ 函数来判断。函数的具体实现逻辑如下: -首先判断 $s$ 和 $t$ 的长度关系,如果 $t$ 的长度大于 $s$,直接返回 `false`;否则,我们用双指针 $i$ 和 $j$ 分别指向 $s$ 和 $t$,初始时 $i$ 和 $j$ 的值均为 $0$。 +首先判断 $s$ 和 $t$ 的长度关系,如果 $t$ 的长度大于 $s$,直接返回 $\textit{false}$;否则,我们用双指针 $i$ 和 $j$ 分别指向 $s$ 和 $t$,初始时 $i$ 和 $j$ 的值均为 $0$。 -如果 $i$ 和 $j$ 指向的字符不同,那么 $t$ 无法通过扩张得到 $s$,直接返回 `false`;否则,我们需要判断 $i$ 指向的字符的连续出现次数 $c_1$ 和 $j$ 指向的字符的连续出现次数 $c_2$ 的关系。如果 $c_1 \lt c_2$ 或者 $c_1 \lt 3$ 并且 $c_1 \neq c_2$,那么 $t$ 无法通过扩张得到 $s$,直接返回 `false`;否则,将 $i$ 和 $j$ 分别右移 $c_1$ 和 $c_2$ 次。继续判断。 +如果 $i$ 和 $j$ 指向的字符不同,那么 $t$ 无法通过扩张得到 $s$,直接返回 $\textit{false}$;否则,我们需要判断 $i$ 指向的字符的连续出现次数 $c_1$ 和 $j$ 指向的字符的连续出现次数 $c_2$ 的关系。如果 $c_1 \lt c_2$ 或者 $c_1 \lt 3$ 并且 $c_1 \neq c_2$,那么 $t$ 无法通过扩张得到 $s$,直接返回 $\textit{false}$;否则,将 $i$ 和 $j$ 分别右移 $c_1$ 和 $c_2$ 次。继续判断。 -如果 $i$ 和 $j$ 都到达了字符串的末尾,那么 $t$ 可以通过扩张得到 $s$,返回 `true`,否则返回 `false`。 +如果 $i$ 和 $j$ 都到达了字符串的末尾,那么 $t$ 可以通过扩张得到 $s$,返回 $\textit{true}$,否则返回 $\textit{false}$。 -时间复杂度 $O(n \times m + \sum_{i=0}^{m-1} w_i)$,其中 $n$ 和 $m$ 分别为字符串 $s$ 和数组 $words$ 的长度,而 $w_i$ 为数组 $words$ 中第 $i$ 个单词的长度。 +时间复杂度 $O(n \times m + \sum_{i=0}^{m-1} w_i)$,其中 $n$ 和 $m$ 分别为字符串 $s$ 和数组 $\textit{words}$ 的长度,而 $w_i$ 为数组 $\textit{words}$ 中第 $i$ 个单词的长度。 diff --git a/solution/0800-0899/0809.Expressive Words/README_EN.md b/solution/0800-0899/0809.Expressive Words/README_EN.md index d7d5225c9d0da..0a5e157baa063 100644 --- a/solution/0800-0899/0809.Expressive Words/README_EN.md +++ b/solution/0800-0899/0809.Expressive Words/README_EN.md @@ -41,7 +41,7 @@ tags:Input: s = "heeellooo", words = ["hello", "hi", "helo"] Output: 1 -Explanation: +Explanation: We can extend "e" and "o" in the word "hello" to get "heeellooo". We can't extend "helo" to get "heeellooo" because the group "ll" is not size 3 or more.@@ -68,7 +68,19 @@ We can't extend "helo" to get "heeellooo" because the gr -### Solution 1 +### Solution 1: Traversal Counting + Two Pointers + +We can traverse the array $\textit{words}$, and for each word $t$ in the array, check if $t$ can be expanded to obtain $s$. If it can, increment the answer by one. + +Therefore, the key problem is to determine if the word $t$ can be expanded to obtain $s$. We use a function $\textit{check}(s, t)$ to determine this. The implementation logic of the function is as follows: + +First, check the length relationship between $s$ and $t$. If the length of $t$ is greater than $s$, return $\textit{false}$ directly. Otherwise, use two pointers $i$ and $j$ to point to $s$ and $t$, respectively, both initially set to $0$. + +If the characters pointed to by $i$ and $j$ are different, then $t$ cannot be expanded to obtain $s$, and we return $\textit{false}$. Otherwise, we need to check the relationship between the consecutive occurrence counts of the characters pointed to by $i$ and $j$, denoted as $c_1$ and $c_2$. If $c_1 \lt c_2$ or $c_1 \lt 3$ and $c_1 \neq c_2$, then $t$ cannot be expanded to obtain $s$, and we return $\textit{false}$. Otherwise, move $i$ and $j$ to the right by $c_1$ and $c_2$ times, respectively, and continue checking. + +If both $i$ and $j$ reach the end of the strings, then $t$ can be expanded to obtain $s$, and we return $\textit{true}$. Otherwise, we return $\textit{false}$. + +The time complexity is $O(n \times m + \sum_{i=0}^{m-1} w_i)$, where $n$ and $m$ are the lengths of the string $s$ and the array $\textit{words}$, respectively, and $w_i$ is the length of the $i$-th word in the array $\textit{words}$. diff --git a/solution/0800-0899/0810.Chalkboard XOR Game/README.md b/solution/0800-0899/0810.Chalkboard XOR Game/README.md index 2f34cfd1417f4..9ec6578b83674 100644 --- a/solution/0800-0899/0810.Chalkboard XOR Game/README.md +++ b/solution/0800-0899/0810.Chalkboard XOR Game/README.md @@ -35,7 +35,7 @@ tags:输入: nums = [1,1,2] 输出: false -解释: +解释: Alice 有两个选择: 擦掉数字 1 或 2。 如果擦掉 1, 数组变成 [1, 2]。剩余数字按位异或得到 1 XOR 2 = 3。那么 Bob 可以擦掉任意数字,因为 Alice 会成为擦掉最后一个数字的人,她总是会输。 如果 Alice 擦掉 2,那么数组变成[1, 1]。剩余数字按位异或得到 1 XOR 1 = 0。Alice 仍然会输掉游戏。 @@ -72,28 +72,28 @@ Alice 有两个选择: 擦掉数字 1 或 2。 ### 方法一:位运算 -根据游戏规则,轮到某个玩家时,如果当前黑板上所有数字按位异或运算结果为 $0$,这个玩家获胜。由于 Alice 先手,因此当 `nums` 中所有数字的异或结果为 $0$ 时,Alice 可以获胜。 +根据游戏规则,轮到某个玩家时,如果当前黑板上所有数字按位异或运算结果为 $0$,这个玩家获胜。由于 Alice 先手,因此当 $\textit{nums}$ 中所有数字的异或结果为 $0$ 时,Alice 可以获胜。 -当 `nums` 中所有数字的异或结果不为 $0$ 时,我们不妨考虑从数组 `nums` 的长度奇偶性来分析 Alice 的获胜情况。 +当 $\textit{nums}$ 中所有数字的异或结果不为 $0$ 时,我们不妨考虑从数组 $\textit{nums}$ 的长度奇偶性来分析 Alice 的获胜情况。 -当 `nums` 的长度为偶数时,如果 Alice 必败,那么只有一种情况,就是 Alice 无论擦掉哪个数字,剩余所有数字的异或结果都等于 $0$。我们来分析一下是否存在这种情况。 +当 $\textit{nums}$ 的长度为偶数时,如果 Alice 必败,那么只有一种情况,就是 Alice 无论擦掉哪个数字,剩余所有数字的异或结果都等于 $0$。我们来分析一下是否存在这种情况。 -假设数组 `nums` 长度为 $n$,并且 $n$ 是偶数,记所有数字异或结尾为 $S$,则有: +假设数组 $\textit{nums}$ 长度为 $n$,并且 $n$ 是偶数,记所有数字异或结尾为 $S$,则有: $$ -S = nums[0] \oplus nums[1] \oplus \cdots \oplus nums[n-1] \neq 0 +S = \textit{nums}[0] \oplus \textit{nums}[1] \oplus \cdots \oplus \textit{nums}[n-1] \neq 0 $$ -我们记 $S_i$ 为数组 `nums` 擦掉第 $i$ 个数字后的异或结果,那么有: +我们记 $S_i$ 为数组 $\textit{nums}$ 擦掉第 $i$ 个数字后的异或结果,那么有: $$ -S_i \oplus nums[i] = S +S_i \oplus \textit{nums}[i] = S $$ -等式两边同时异或 $nums[i]$,得到: +等式两边同时异或 $\textit{nums}[i]$,得到: $$ -S_i = S \oplus nums[i] +S_i = S \oplus \textit{nums}[i] $$ 如果无论 Alice 擦掉哪个数字,剩余所有数字的异或结果都等于 $0$,那么对所有 $i$,都有 $S_i = 0$,即: @@ -102,19 +102,19 @@ $$ S_0 \oplus S_1 \oplus \cdots \oplus S_{n-1} = 0 $$ -我们将 $S_i = S \oplus nums[i]$ 代入上式,得到: +我们将 $S_i = S \oplus \textit{nums}[i]$ 代入上式,得到: $$ -S \oplus nums[0] \oplus S \oplus nums[1] \oplus \cdots \oplus S \oplus nums[n-1] = 0 +S \oplus \textit{nums}[0] \oplus S \oplus \textit{nums}[1] \oplus \cdots \oplus S \oplus \textit{nums}[n-1] = 0 $$ -上式共有 $n$(偶数)个 $S$,而 $nums[0] \oplus nums[1] \oplus \cdots \oplus nums[n-1]$ 也等于 $S$,因此上式等价于 $0 \oplus S = 0$。这与 $S \neq 0$ 矛盾,因此不存在这种情况。因此当 `nums` 的长度为偶数时,Alice 必胜。 +上式共有 $n$(偶数)个 $S$,而 $\textit{nums}[0] \oplus \textit{nums}[1] \oplus \cdots \oplus \textit{nums}[n-1]$ 也等于 $S$,因此上式等价于 $0 \oplus S = 0$。这与 $S \neq 0$ 矛盾,因此不存在这种情况。因此当 $\textit{nums}$ 的长度为偶数时,Alice 必胜。 如果长度为奇数,那么 Alice 擦掉一个数字后,剩余数字个数为偶数,也就是将偶数长度的情况留给 Bob,那么 Bob 必胜,也即 Alice 必败。 -综上,当 `nums` 的长度为偶数,或者 `nums` 中所有数字的异或结果为 $0$ 时,Alice 可以获胜。 +综上,当 $\textit{nums}$ 的长度为偶数,或者 $\textit{nums}$ 中所有数字的异或结果为 $0$ 时,Alice 可以获胜。 -时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组 `nums` 的长度。 +时间复杂度 $O(n)$,其中 $n$ 为数组 $\textit{nums}$ 的长度。空间复杂度 $O(1)$。 diff --git a/solution/0800-0899/0810.Chalkboard XOR Game/README_EN.md b/solution/0800-0899/0810.Chalkboard XOR Game/README_EN.md index bd285cf46f7b9..22c8b94422bd8 100644 --- a/solution/0800-0899/0810.Chalkboard XOR Game/README_EN.md +++ b/solution/0800-0899/0810.Chalkboard XOR Game/README_EN.md @@ -34,9 +34,9 @@ tags:Input: nums = [1,1,2] Output: false -Explanation: -Alice has two choices: erase 1 or erase 2. -If she erases 1, the nums array becomes [1, 2]. The bitwise XOR of all the elements of the chalkboard is 1 XOR 2 = 3. Now Bob can remove any element he wants, because Alice will be the one to erase the last element and she will lose. +Explanation: +Alice has two choices: erase 1 or erase 2. +If she erases 1, the nums array becomes [1, 2]. The bitwise XOR of all the elements of the chalkboard is 1 XOR 2 = 3. Now Bob can remove any element he wants, because Alice will be the one to erase the last element and she will lose. If Alice erases 2 first, now nums become [1, 1]. The bitwise XOR of all the elements of the chalkboard is 1 XOR 1 = 0. Alice will lose.@@ -68,7 +68,51 @@ If Alice erases 2 first, now nums become [1, 1]. The bitwise XOR of all the elem -### Solution 1 +### Solution 1: Bit Manipulation + +According to the game rules, if the XOR result of all numbers on the blackboard is $0$ when it is a player's turn, that player wins. Since Alice goes first, if the XOR result of all numbers in $\textit{nums}$ is $0$, Alice can win. + +When the XOR result of all numbers in $\textit{nums}$ is not $0$, let's analyze Alice's winning situation based on the parity of the length of the array $\textit{nums}$. + +When the length of $\textit{nums}$ is even, if Alice is destined to lose, there is only one situation: no matter which number Alice erases, the XOR result of all remaining numbers equals $0$. Let's analyze whether this situation exists. + +Assume the length of the array $\textit{nums}$ is $n$, and $n$ is even. Let the XOR result of all numbers be $S$, then: + +$$ +S = \textit{nums}[0] \oplus \textit{nums}[1] \oplus \cdots \oplus \textit{nums}[n-1] \neq 0 +$$ + +Let $S_i$ be the XOR result after erasing the $i$-th number from the array $\textit{nums}$, then: + +$$ +S_i \oplus \textit{nums}[i] = S +$$ + +XOR both sides of the equation by $\textit{nums}[i]$, we get: + +$$ +S_i = S \oplus \textit{nums}[i] +$$ + +If no matter which number Alice erases, the XOR result of all remaining numbers equals $0$, then for all $i$, we have $S_i = 0$, i.e., + +$$ +S_0 \oplus S_1 \oplus \cdots \oplus S_{n-1} = 0 +$$ + +Substitute $S_i = S \oplus \textit{nums}[i]$ into the above equation, we get: + +$$ +S \oplus \textit{nums}[0] \oplus S \oplus \textit{nums}[1] \oplus \cdots \oplus S \oplus \textit{nums}[n-1] = 0 +$$ + +There are $n$ (even) $S$ terms in the above equation, and $\textit{nums}[0] \oplus \textit{nums}[1] \oplus \cdots \oplus \textit{nums}[n-1]$ also equals $S$, so the equation is equivalent to $0 \oplus S = 0$. This contradicts $S \neq 0$, so this situation does not exist. Therefore, when the length of $\textit{nums}$ is even, Alice is guaranteed to win. + +If the length is odd, then after Alice erases a number, the remaining numbers are even in length, leaving Bob with an even-length situation, which means Bob is guaranteed to win, and thus Alice is destined to lose. + +In conclusion, Alice can win when the length of $\textit{nums}$ is even or the XOR result of all numbers in $\textit{nums}$ is $0$. + +The time complexity is $O(n)$, where $n$ is the length of the array $\textit{nums}$. The space complexity is $O(1)$. diff --git a/solution/3300-3399/3369.Design an Array Statistics Tracker/README.md b/solution/3300-3399/3369.Design an Array Statistics Tracker/README.md index 6ff0e6599ffaa..29768518fad33 100644 --- a/solution/3300-3399/3369.Design an Array Statistics Tracker/README.md +++ b/solution/3300-3399/3369.Design an Array Statistics Tracker/README.md @@ -10,7 +10,7 @@ tags: -# [3369. Design an Array Statistics Tracker 🔒](https://leetcode.cn/problems/design-an-array-statistics-tracker) +# [3369. 设计数组统计跟踪器 🔒](https://leetcode.cn/problems/design-an-array-statistics-tracker) [English Version](/solution/3300-3399/3369.Design%20an%20Array%20Statistics%20Tracker/README_EN.md) @@ -18,80 +18,82 @@ tags: -Design a data structure that keeps track of the values in it and answers some queries regarding their mean, median, and mode.
+设计一个数据结构来跟踪它其中的值,并回答一些有关其平均值、中位数和众数的询问。
-Implement the
+StatisticsTracker
class.实现
StatisticsTracker
类。
StatisticsTracker()
: Initialize the StatisticsTracker
object with an empty array.void addNumber(int number)
: Add number
to the data structure.void removeFirstAddedNumber()
: Remove the earliest added number from the data structure.int getMean()
: Return the floored mean of the numbers in the data structure.int getMedian()
: Return the median of the numbers in the data structure.int getMode()
: Return the mode of the numbers in the data structure. If there are multiple modes, return the smallest one.StatisticsTracker()
:用空数组初始化 StatisticsTracker
对象。void addNumber(int number)
:将 number
添加到数据结构中。void removeFirstAddedNumber()
:从数据结构删除最早添加的数字。int getMean()
:返回数据结构中数字向下取整的 平均值。int getMedian()
:返回数据结构中数字的 中位数。int getMode()
:返回数据结构中数字的 众数。如果有多个众数,返回最小的那个。Note:
+注意:
-
Example 1:
+ +示例 1:
Input: 输入: Output: 输出: Explanation 解释:
-["StatisticsTracker", "addNumber", "addNumber", "addNumber", "addNumber", "getMean", "getMedian", "getMode", "removeFirstAddedNumber", "getMode"]
+
+["StatisticsTracker", "addNumber", "addNumber", "addNumber", "addNumber", "getMean", "getMedian", "getMode", "removeFirstAddedNumber", "getMode"]
[[], [4], [4], [2], [3], [], [], [], [], []]
+
[null, null, null, null, null, 3, 4, 4, null, 2]
-statisticsTracker.addNumber(4); // The data structure now contains [4]
-statisticsTracker.addNumber(4); // The data structure now contains [4, 4]
-statisticsTracker.addNumber(2); // The data structure now contains [4, 4, 2]
-statisticsTracker.addNumber(3); // The data structure now contains [4, 4, 2, 3]
+statisticsTracker.addNumber(4); // 现在数据结构中有 [4]
+statisticsTracker.addNumber(4); // 现在数据结构中有 [4, 4]
+statisticsTracker.addNumber(2); // 现在数据结构中有 [4, 4, 2]
+statisticsTracker.addNumber(3); // 现在数据结构中有 [4, 4, 2, 3]
statisticsTracker.getMean(); // return 3
statisticsTracker.getMedian(); // return 4
statisticsTracker.getMode(); // return 4
-statisticsTracker.removeFirstAddedNumber(); // The data structure now contains [4, 2, 3]
+statisticsTracker.removeFirstAddedNumber(); // 现在数据结构中有 [4, 2, 3]
statisticsTracker.getMode(); // return 2
Example 2:
+示例 2:
Input: 输入: Output: 输出: Explanation 解释:
-["StatisticsTracker", "addNumber", "addNumber", "getMean", "removeFirstAddedNumber", "addNumber", "addNumber", "removeFirstAddedNumber", "getMedian", "addNumber", "getMode"]
+
+["StatisticsTracker", "addNumber", "addNumber", "getMean", "removeFirstAddedNumber", "addNumber", "addNumber", "removeFirstAddedNumber", "getMedian", "addNumber", "getMode"]
[[], [9], [5], [], [], [5], [6], [], [], [8], []]
+
[null, null, null, 7, null, null, null, null, 6, null, 5]
-statisticsTracker.addNumber(9); // The data structure now contains [9]
-statisticsTracker.addNumber(5); // The data structure now contains [9, 5]
+statisticsTracker.addNumber(9); // 现在数据结构中有 [9]
+statisticsTracker.addNumber(5); // 现在数据结构中有 [9, 5]
statisticsTracker.getMean(); // return 7
-statisticsTracker.removeFirstAddedNumber(); // The data structure now contains [5]
-statisticsTracker.addNumber(5); // The data structure now contains [5, 5]
-statisticsTracker.addNumber(6); // The data structure now contains [5, 5, 6]
-statisticsTracker.removeFirstAddedNumber(); // The data structure now contains [5, 6]
+statisticsTracker.removeFirstAddedNumber(); // 现在数据结构中有 [5]
+statisticsTracker.addNumber(5); // 现在数据结构中有 [5, 5]
+statisticsTracker.addNumber(6); // 现在数据结构中有 [5, 5, 6]
+statisticsTracker.removeFirstAddedNumber(); // 现在数据结构中有 [5, 6]
statisticsTracker.getMedian(); // return 6
-statisticsTracker.addNumber(8); // The data structure now contains [5, 6, 8]
+statisticsTracker.addNumber(8); // 现在数据结构中有 [5, 6, 8]
statisticsTracker.getMode(); // return 5
-
Constraints:
+ +提示:
1 <= number <= 109
105
calls will be made to addNumber
, removeFirstAddedNumber
, getMean
, getMedian
, and getMode
in total.removeFirstAddedNumber
, getMean
, getMedian
, and getMode
will be called only if there is at least one element in the data structure.addNumber
,removeFirstAddedNumber
,getMean
,getMedian
和 getMode
的总调用次数最多为 105
。removeFirstAddedNumber
,getMean
,getMedian
和 getMode
只会在数据结构中至少有一个元素时被调用。