LeetCode Weekly Contest 369 Summary
Overview
This article is a summary of the contest. I don't plan to discuss each problem in detail, but will provide general ideas. The point of this article is self-reflection and improvement.
After reviewing the contest, it is not so difficult. Here is a brief description of my performance on each problem:
- Problem 1: Simple simulation problem, an easy one.
- Problem 2: Not difficult, but requires consideration of multiple cases. Unfortunately, I didn't think thoroughly, resulting in 3 WA 😒.
- Problem 3: a Medium-level DP problem. Initially struggled to come up with a solution, wasted time on the unsolved problem 4, but eventually solved it quickly 😋.
- Problem 4: Despite being a hard-level problem and not solved during the contest, the code only exceeded time limits. After the contest, I figured out an optimization method by myself. Note that the messy logic during coding led to 2 WA 😒.
I. Find the K-or of an Array
Problem Description:
You are given a 0-indexed integer array
nums, and an integerk.The K-or of
numsis a non-negative integer that satisfies the following:
- The
ithbit is set in the K-or if and only if there are at leastkelements ofnumsin which bitiis set.Return the K-or of
nums.Note that a bit
iis set inxif(2i AND x) == 2i, whereANDis the bitwiseANDoperator.Example 1:
1
2
3
4
5
6
7 Input: nums = [7,12,9,8,9,15], k = 4
Output: 9
Explanation: Bit 0 is set at nums[0], nums[2], nums[4], and nums[5].
Bit 1 is set at nums[0], and nums[5].
Bit 2 is set at nums[0], nums[1], and nums[5].
Bit 3 is set at nums[1], nums[2], nums[3], nums[4], and nums[5].
Only bits 0 and 3 are set in at least k elements of the array, and bits i >= 4 are not set in any of the array's elements. Hence, the answer is 2^0 + 2^3 = 9.Example 2:
1
2
3 Input: nums = [2,12,1,11,4,5], k = 6
Output: 0
Explanation: Since k == 6 == nums.length, the 6-or of the array is equal to the bitwise AND of all its elements. Hence, the answer is 2 AND 12 AND 1 AND 11 AND 4 AND 5 = 0.Example 3:
1
2
3 Input: nums = [10,8,5,9,11,6,8], k = 1
Output: 15
Explanation: Since k == 1, the 1-or of the array is equal to the bitwise OR of all its elements. Hence, the answer is 10 OR 8 OR 5 OR 9 OR 11 OR 6 OR 8 = 15.Constraints:
1 <= nums.length <= 500 <= nums[i] < 2311 <= k <= nums.length
The problem description is a bit hard to understand. Combining it with examples during the contest was necessary for quick understanding.
Bitwise simulation:
1 | class Solution { |
Time complexity: $O(n)$
II. Minimum Equal Sum of Two Arrays After Replacing Zeros
Problem Description:
You are given two arrays
nums1andnums2consisting of positive integers.You have to replace all the
0's in both arrays with strictly positive integers such that the sum of elements of both arrays becomes equal.Return the minimum equal sum you can obtain, or
-1if it is impossible.Example 1:
1
2
3
4
5
6 Input: nums1 = [3,2,0,1,0], nums2 = [6,5,0]
Output: 12
Explanation: We can replace 0's in the following way:
- Replace the two 0's in nums1 with the values 2 and 4. The resulting array is nums1 = [3,2,2,1,4].
- Replace the 0 in nums2 with the value 1. The resulting array is nums2 = [6,5,1].
Both arrays have an equal sum of 12. It can be shown that it is the minimum sum we can obtain.Example 2:
1
2
3 Input: nums1 = [2,0,2,0], nums2 = [1,4]
Output: -1
Explanation: It is impossible to make the sum of both arrays equal.Constraints:
1 <= nums1.length, nums2.length <= 1050 <= nums1[i], nums2[i] <= 106
- If there are
kzeros innums1, its sum must increase by at leastkafter replacement. - If
nums1has at least one zero, its sum after replacement can be any value greater thansum(nums1). - Similar for
nums2.
Return type of the function is long. Array length is at most $10^5$, elements are at most $10^6$, and the sum is at most $10^{11}$, exceeding the limit of a 32-bit integer, which reminds us that all the intermediate results should be stored in long type. In fact, it is a common practice to replace int with long in coding contests to avoid integer overflow.
The key is to identify conditions where equality does not hold. A mistake in this aspect led to three WA:
1 | import java.util.Arrays; |
III. Minimum Increment Operations to Make Array Beautiful
Problem Description:
You are given a 0-indexed integer array
numshaving lengthn, and an integerk.You can perform the following increment operation any number of times (including zero):
- Choose an index
iin the range[0, n - 1], and increasenums[i]by1.An array is considered beautiful if, for any subarray with a size of
3or more, its maximum element is greater than or equal tok.Return an integer denoting the minimum number of increment operations needed to make
numsbeautiful.A subarray is a contiguous non-empty sequence of elements within an array.
Example 1:
1
2
3
4
5
6
7
8
9
10 Input: nums = [2,3,0,0,2], k = 4
Output: 3
Explanation: We can perform the following increment operations to make nums beautiful:
Choose index i = 1 and increase nums[1] by 1 -> [2,4,0,0,2].
Choose index i = 4 and increase nums[4] by 1 -> [2,4,0,0,3].
Choose index i = 4 and increase nums[4] by 1 -> [2,4,0,0,4].
The subarrays with a size of 3 or more are: [2,4,0], [4,0,0], [0,0,4], [2,4,0,0], [4,0,0,4], [2,4,0,0,4].
In all the subarrays, the maximum element is equal to k = 4, so nums is now beautiful.
It can be shown that nums cannot be made beautiful with fewer than 3 increment operations.
Hence, the answer is 3.Example 2:
1
2
3
4
5
6
7
8
9 Input: nums = [0,1,3,3], k = 5
Output: 2
Explanation: We can perform the following increment operations to make nums beautiful:
Choose index i = 2 and increase nums[2] by 1 -> [0,1,4,3].
Choose index i = 2 and increase nums[2] by 1 -> [0,1,5,3].
The subarrays with a size of 3 or more are: [0,1,5], [1,5,3], [0,1,5,3].
In all the subarrays, the maximum element is equal to k = 5, so nums is now beautiful.
It can be shown that nums cannot be made beautiful with fewer than 2 increment operations.
Hence, the answer is 2.Example 3:
1
2
3
4
5 Input: nums = [1,1,2], k = 1
Output: 0
Explanation: The only subarray with a size of 3 or more in this example is [1,1,2].
The maximum element, 2, is already greater than k = 1, so we don't need any increment operation.
Hence, the answer is 0.Constraints:
3 <= n == nums.length <= 1050 <= nums[i] <= 1090 <= k <= 109
An array is considered beautiful if, for any subarray with a size of
3or more, its maximum element is greater than or equal tok.
This condition is equivalent to having every subarray of length 3 with a maximum element $\ge k$.
Obviously, we should try to ensure that in every three consecutive elements, at least one element is $\ge k$. However, it is unclear which elements should be increased to $k$. To address this, let's use DP.
1️⃣DP definition: dp[i]: the minimum increment operations to make nums[0:i] a beautiful array and nums[i] $\ge k$. — Here are three bold points.
If nums[i] $\ge k$, then nums[i - 2 : i] forms a subarray of length 3 that can be covered, satisfying the condition for being a beautiful array. This coverage simultaneously indicates that we need to ensure nums[0:(i-3)] is also a beautiful array to make nums[0:i] a beautiful array. Results from dp[i - 3], dp[i - 2], and dp[i - 1] all satisfy this requirement; thus, we take the minimum value in them:
2️⃣Recurrence relation: $dp[i] = \max\set{0,k-nums[i]} + \min\set{dp[i - 1], dp[i - 2], dp[i - 3]}$
3️⃣Answer: Choose the minimum value among dp[n - 3], dp[n - 2], and dp[n - 1], all of which can guarantee nums being a beautiful array by DP definition.
1 | import java.util.Arrays; |
IV. Maximum Points After Collecting Coins From All Nodes
Problem Description:
There exists an undirected tree rooted at node
0withnnodes labeled from0ton - 1. You are given a 2D integer arrayedgesof lengthn - 1, whereedges[i] = [ai, bi]indicates that there is an edge between nodesaiandbiin the tree. You are also given a 0-indexed arraycoinsof sizenwherecoins[i]indicates the number of coins in the vertexi, and an integerk.Starting from the root, you have to collect all the coins such that the coins at a node can only be collected if the coins of its ancestors have been already collected.
Coins at
nodeican be collected in one of the following ways:
- Collect all the coins, but you will get
coins[i] - kpoints. Ifcoins[i] - kis negative then you will loseabs(coins[i] - k)points.- Collect all the coins, but you will get
floor(coins[i] / 2)points. If this way is used, then for all thenodejpresent in the subtree ofnodei,coins[j]will get reduced tofloor(coins[j] / 2).Return the maximum points you can get after collecting the coins from all the tree nodes.
Example 1:
1
2
3
4
5
6
7
8 Input: edges = [[0,1],[1,2],[2,3]], coins = [10,10,3,3], k = 5
Output: 11
Explanation:
Collect all the coins from node 0 using the first way. Total points = 10 - 5 = 5.
Collect all the coins from node 1 using the first way. Total points = 5 + (10 - 5) = 10.
Collect all the coins from node 2 using the second way so coins left at node 3 will be floor(3 / 2) = 1. Total points = 10 + floor(3 / 2) = 11.
Collect all the coins from node 3 using the second way. Total points = 11 + floor(1 / 2) = 11.
It can be shown that the maximum points we can get after collecting coins from all the nodes is 11.Example 2:
1
2
3
4 Input: edges = [[0,1],[0,2]], coins = [8,4,4], k = 0
Output: 16
Explanation:
Coins will be collected from all the nodes using the first way. Therefore, total points = (8 - 0) + (4 - 0) + (4 - 0) = 16.Constraints:
n == coins.length2 <= n <= 1050 <= coins[i] <= 104edges.length == n - 10 <= edges[i][0], edges[i][1] < n0 <= k <= 104
1️⃣Build the tree. It's essentially building a graph, and we need to perform DFS starting from node 0 to simulate tree traversal.
2️⃣There are two ways to collect coins (the problem is intentionally written in complicated words, requiring simplification):
- Option 1: Currently-collected coins plus
coins[i] - k(regardless of sign). - Option 2:
floor(coins[i] / 2)is essentially integer division, we should optimize the division using bitwise operation i.e.,coins[i] >> 1. Bitwise operation also has the advantage that if the current node has $k$ ancestors choosing Option 2, then the coin count for that node iscoins[i] >> k, avoiding the time cost of computing $2^k$ and division by $2^k$.
Based on these two options, we can write a recursive function for pre-order traversal:
1 | /** |
Up to this point, I had written the code during the contest but still encountered a timeout. Later, I came up with the following optimization ideas:
3️⃣ $\forall i, coins[i] \le 10^4$, and $\log_2(10^4) \approx 13.8$. Thus, as long as the ancestors of the current subtree have chosen Option 2 at least 14 times, the coin count for all nodes in this subtree will continuously halve to 0.
This is basically a pruning technique, and we check it at the beginning of the recur function:
1 | if (half >= 14) return 0; |
4️⃣Speaking of recursion, we think about divide and conquer paradigms, which then lead to thoughts about DP paradigms. What is the difference between the two? — DP reuses results of subproblems, making it more efficient.
Although the process of traversing the tree cannot be written as an iteration, we can use a map to cache results of subproblems: the key is (nodes[i], half), and the value is the number of collected coins.
1 | private final HashMap<Node, HashMap<Long, Long>> dpMap = new HashMap<>(); |
With these two optimization steps, the code successfully passed:
1 | import java.util.ArrayList; |

