diff --git a/solution/2800-2899/2855.Minimum Right Shifts to Sort the Array/README.md b/solution/2800-2899/2855.Minimum Right Shifts to Sort the Array/README.md new file mode 100644 index 0000000000000..bf4714be0714a --- /dev/null +++ b/solution/2800-2899/2855.Minimum Right Shifts to Sort the Array/README.md @@ -0,0 +1,164 @@ +# [2855. 使数组成为递增数组的最少右移次数](https://leetcode.cn/problems/minimum-right-shifts-to-sort-the-array) + +[English Version](/solution/2800-2899/2855.Minimum%20Right%20Shifts%20to%20Sort%20the%20Array/README_EN.md) + +## 题目描述 + + + +

给你一个长度为 n 下标从 0 开始的数组 nums ,数组中的元素为 互不相同 的正整数。请你返回让 nums 成为递增数组的 最少右移 次数,如果无法得到递增数组,返回 -1

+ +

一次 右移 指的是同时对所有下标进行操作,将下标为 i 的元素移动到下标 (i + 1) % n 处。

+ + + +

示例 1:

+ +
+输入:nums = [3,4,5,1,2]
+输出:2
+解释:
+第一次右移后,nums = [2,3,4,5,1] 。
+第二次右移后,nums = [1,2,3,4,5] 。
+现在 nums 是递增数组了,所以答案为 2 。
+
+ +

示例 2:

+ +
+输入:nums = [1,3,5]
+输出:0
+解释:nums 已经是递增数组了,所以答案为 0 。
+ +

示例 3:

+ +
+输入:nums = [2,1,4]
+输出:-1
+解释:无法将数组变为递增数组。
+
+ + + +

提示:

+ + + +## 解法 + + + +**方法一:直接遍历** + +我们先用一个指针 $i$ 从左到右遍历数组 $nums,ドル找出一段连续的递增序列,直到 $i$ 到达数组末尾或者 $nums[i - 1] \gt nums[i]$。接下来我们用另一个指针 $k$ 从 $i + 1$ 开始遍历数组 $nums,ドル找出一段连续的递增序列,直到 $k$ 到达数组末尾或者 $nums[k - 1] \gt nums[k]$ 且 $nums[k] \gt nums[0]$。如果 $k$ 到达数组末尾,说明数组已经是递增的,返回 $n - i$;否则返回 $-1$。 + +时间复杂度 $O(n),ドル空间复杂度 $O(1)$。其中 $n$ 是数组 $nums$ 的长度。 + + + +### **Python3** + + + +```python +class Solution: + def minimumRightShifts(self, nums: List[int]) -> int: + n = len(nums) + i = 1 + while i < n and nums[i - 1] < nums[i]: + i += 1 + k = i + 1 + while k < n and nums[k - 1] < nums[k] < nums[0]: + k += 1 + return -1 if k < n else n - i +``` + +### **Java** + + + +```java +class Solution { + public int minimumRightShifts(List nums) { + int n = nums.size(); + int i = 1; + while (i < n && nums.get(i - 1) < nums.get(i)) { + ++i; + } + int k = i + 1; + while (k < n && nums.get(k - 1) < nums.get(k) && nums.get(k) < nums.get(0)) { + ++k; + } + return k < n ? -1 : n - i; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + int minimumRightShifts(vector& nums) { + int n = nums.size(); + int i = 1; + while (i < n && nums[i - 1] < nums[i]) { + ++i; + } + int k = i + 1; + while (k < n && nums[k - 1] < nums[k] && nums[k] < nums[0]) { + ++k; + } + return k < n ? -1 : n - i; + } +}; +``` + +### **Go** + +```go +func minimumRightShifts(nums []int) int { + n := len(nums) + i := 1 + for i < n && nums[i-1] < nums[i] { + i++ + } + k := i + 1 + for k < n && nums[k-1] < nums[k] && nums[k] < nums[0] { + k++ + } + if k < n { + return -1 + } + return n - i +} +``` + +### **TypeScript** + +```ts +function minimumRightShifts(nums: number[]): number { + const n = nums.length; + let i = 1; + while (i < n && nums[i - 1] < nums[i]) { + ++i; + } + let k = i + 1; + while (k < n && nums[k - 1] < nums[k] && nums[k] < nums[0]) { + ++k; + } + return k < n ? -1 : n - i; +} +``` + +### **...** + +``` + +``` + + diff --git a/solution/2800-2899/2855.Minimum Right Shifts to Sort the Array/README_EN.md b/solution/2800-2899/2855.Minimum Right Shifts to Sort the Array/README_EN.md new file mode 100644 index 0000000000000..7da9bb2f57725 --- /dev/null +++ b/solution/2800-2899/2855.Minimum Right Shifts to Sort the Array/README_EN.md @@ -0,0 +1,148 @@ +# [2855. Minimum Right Shifts to Sort the Array](https://leetcode.com/problems/minimum-right-shifts-to-sort-the-array) + +[中文文档](/solution/2800-2899/2855.Minimum%20Right%20Shifts%20to%20Sort%20the%20Array/README.md) + +## Description + +

You are given a 0-indexed array nums of length n containing distinct positive integers. Return the minimum number of right shifts required to sort nums and -1 if this is not possible.

+ +

A right shift is defined as shifting the element at index i to index (i + 1) % n, for all indices.

+ + +

Example 1:

+ +
+Input: nums = [3,4,5,1,2]
+Output: 2
+Explanation: 
+After the first right shift, nums = [2,3,4,5,1].
+After the second right shift, nums = [1,2,3,4,5].
+Now nums is sorted; therefore the answer is 2.
+
+ +

Example 2:

+ +
+Input: nums = [1,3,5]
+Output: 0
+Explanation: nums is already sorted therefore, the answer is 0.
+ +

Example 3:

+ +
+Input: nums = [2,1,4]
+Output: -1
+Explanation: It's impossible to sort the array using right shifts.
+
+ + +

Constraints:

+ + + +## Solutions + + + +### **Python3** + +```python +class Solution: + def minimumRightShifts(self, nums: List[int]) -> int: + n = len(nums) + i = 1 + while i < n and nums[i - 1] < nums[i]: + i += 1 + k = i + 1 + while k < n and nums[k - 1] < nums[k] < nums[0]: + k += 1 + return -1 if k < n else n - i +``` + +### **Java** + +```java +class Solution { + public int minimumRightShifts(List nums) { + int n = nums.size(); + int i = 1; + while (i < n && nums.get(i - 1) < nums.get(i)) { + ++i; + } + int k = i + 1; + while (k < n && nums.get(k - 1) < nums.get(k) && nums.get(k) < nums.get(0)) { + ++k; + } + return k < n ? -1 : n - i; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + int minimumRightShifts(vector& nums) { + int n = nums.size(); + int i = 1; + while (i < n && nums[i - 1] < nums[i]) { + ++i; + } + int k = i + 1; + while (k < n && nums[k - 1] < nums[k] && nums[k] < nums[0]) { + ++k; + } + return k < n ? -1 : n - i; + } +}; +``` + +### **Go** + +```go +func minimumRightShifts(nums []int) int { + n := len(nums) + i := 1 + for i < n && nums[i-1] < nums[i] { + i++ + } + k := i + 1 + for k < n && nums[k-1] < nums[k] && nums[k] < nums[0] { + k++ + } + if k < n { + return -1 + } + return n - i +} +``` + +### **TypeScript** + +```ts +function minimumRightShifts(nums: number[]): number { + const n = nums.length; + let i = 1; + while (i < n && nums[i - 1] < nums[i]) { + ++i; + } + let k = i + 1; + while (k < n && nums[k - 1] < nums[k] && nums[k] < nums[0]) { + ++k; + } + return k < n ? -1 : n - i; +} +``` + +### **...** + +``` + +``` + + diff --git a/solution/2800-2899/2855.Minimum Right Shifts to Sort the Array/Solution.cpp b/solution/2800-2899/2855.Minimum Right Shifts to Sort the Array/Solution.cpp new file mode 100644 index 0000000000000..4fd4630b66930 --- /dev/null +++ b/solution/2800-2899/2855.Minimum Right Shifts to Sort the Array/Solution.cpp @@ -0,0 +1,15 @@ +class Solution { +public: + int minimumRightShifts(vector& nums) { + int n = nums.size(); + int i = 1; + while (i < n && nums[i - 1] < nums[i]) { + ++i; + } + int k = i + 1; + while (k < n && nums[k - 1] < nums[k] && nums[k] < nums[0]) { + ++k; + } + return k < n ? -1 : n - i; + } +}; \ No newline at end of file diff --git a/solution/2800-2899/2855.Minimum Right Shifts to Sort the Array/Solution.go b/solution/2800-2899/2855.Minimum Right Shifts to Sort the Array/Solution.go new file mode 100644 index 0000000000000..7495b38ee5fab --- /dev/null +++ b/solution/2800-2899/2855.Minimum Right Shifts to Sort the Array/Solution.go @@ -0,0 +1,15 @@ +func minimumRightShifts(nums []int) int { + n := len(nums) + i := 1 + for i < n && nums[i-1] < nums[i] { + i++ + } + k := i + 1 + for k < n && nums[k-1] < nums[k] && nums[k] < nums[0] { + k++ + } + if k < n { + return -1 + } + return n - i +} \ No newline at end of file diff --git a/solution/2800-2899/2855.Minimum Right Shifts to Sort the Array/Solution.java b/solution/2800-2899/2855.Minimum Right Shifts to Sort the Array/Solution.java new file mode 100644 index 0000000000000..c26bde526d312 --- /dev/null +++ b/solution/2800-2899/2855.Minimum Right Shifts to Sort the Array/Solution.java @@ -0,0 +1,14 @@ +class Solution { + public int minimumRightShifts(List nums) { + int n = nums.size(); + int i = 1; + while (i < n && nums.get(i - 1) < nums.get(i)) { + ++i; + } + int k = i + 1; + while (k < n && nums.get(k - 1) < nums.get(k) && nums.get(k) < nums.get(0)) { + ++k; + } + return k < n ? -1 : n - i; + } +} \ No newline at end of file diff --git a/solution/2800-2899/2855.Minimum Right Shifts to Sort the Array/Solution.py b/solution/2800-2899/2855.Minimum Right Shifts to Sort the Array/Solution.py new file mode 100644 index 0000000000000..eb0c6b19d492c --- /dev/null +++ b/solution/2800-2899/2855.Minimum Right Shifts to Sort the Array/Solution.py @@ -0,0 +1,10 @@ +class Solution: + def minimumRightShifts(self, nums: List[int]) -> int: + n = len(nums) + i = 1 + while i < n and nums[i - 1] < nums[i]: + i += 1 + k = i + 1 + while k < n and nums[k - 1] < nums[k] < nums[0]: + k += 1 + return -1 if k < n else n - i diff --git a/solution/2800-2899/2855.Minimum Right Shifts to Sort the Array/Solution.ts b/solution/2800-2899/2855.Minimum Right Shifts to Sort the Array/Solution.ts new file mode 100644 index 0000000000000..ad1f149738f63 --- /dev/null +++ b/solution/2800-2899/2855.Minimum Right Shifts to Sort the Array/Solution.ts @@ -0,0 +1,12 @@ +function minimumRightShifts(nums: number[]): number { + const n = nums.length; + let i = 1; + while (i < n && nums[i - 1] < nums[i]) { + ++i; + } + let k = i + 1; + while (k < n && nums[k - 1] < nums[k] && nums[k] < nums[0]) { + ++k; + } + return k < n ? -1 : n - i; +} diff --git a/solution/2800-2899/2856.Minimum Array Length After Pair Removals/README.md b/solution/2800-2899/2856.Minimum Array Length After Pair Removals/README.md new file mode 100644 index 0000000000000..0d0575725fbad --- /dev/null +++ b/solution/2800-2899/2856.Minimum Array Length After Pair Removals/README.md @@ -0,0 +1,247 @@ +# [2856. 删除数对后的最小数组长度](https://leetcode.cn/problems/minimum-array-length-after-pair-removals) + +[English Version](/solution/2800-2899/2856.Minimum%20Array%20Length%20After%20Pair%20Removals/README_EN.md) + +## 题目描述 + + + +

给你一个下标从 0 开始的 非递减 整数数组 nums

+ +

你可以执行以下操作任意次:

+ +
    +
  • 选择 两个 下标 ij ,满足 i < jnums[i] < nums[j]
  • +
  • nums 中下标在 ij 处的元素删除。剩余元素按照原来的顺序组成新的数组,下标也重新从 0 开始编号。
  • +
+ +

请你返回一个整数,表示执行以上操作任意次后(可以执行 0 次),nums 数组的 最小 数组长度。

+ + + +

示例 1:

+ +
+输入:nums = [1,3,4,9]
+输出:0
+解释:一开始,nums = [1, 3, 4, 9] 。
+第一次操作,我们选择下标 0 和 1 ,满足 nums[0] < nums[1] <=> 1 < 3 。
+删除下标 0 和 1 处的元素,nums 变成 [4, 9] 。
+下一次操作,我们选择下标 0 和 1 ,满足 nums[0] < nums[1] <=> 4 < 9 。
+删除下标 0 和 1 处的元素,nums 变成空数组 [] 。
+所以,可以得到的最小数组长度为 0 。
+ +

示例 2:

+ +
+输入:nums = [2,3,6,9]
+输出:0
+解释:一开始,nums = [2, 3, 6, 9] 。
+第一次操作,我们选择下标 0 和 2 ,满足 nums[0] < nums[2] <=> 2 < 6 。
+删除下标 0 和 2 处的元素,nums 变成 [3, 9] 。
+下一次操作,我们选择下标 0 和 1 ,满足 nums[0] < nums[1] <=> 3 < 9 。
+删除下标 0 和 1 处的元素,nums 变成空数组 [] 。
+所以,可以得到的最小数组长度为 0 。
+
+ +

示例 3:

+ +
+输入:nums = [1,1,2]
+输出:1
+解释:一开始,nums = [1, 1, 2] 。
+第一次操作,我们选择下标 0 和 2 ,满足 nums[0] < nums[2] <=> 1 < 2 。
+删除下标 0 和 2 处的元素,nums 变成 [1] 。
+无法对数组再执行操作。
+所以,可以得到的最小数组长度为 1 。
+
+ + + +

提示:

+ +
    +
  • 1 <= nums.length <= 105
  • +
  • 1 <= nums[i] <= 109
  • +
  • nums非递减 数组。
  • +
+ +## 解法 + + + +**方法一:贪心 + 优先队列(大根堆)** + +我们用一个哈希表 $cnt$ 统计数组 $nums$ 中每个元素的出现次数,然后将 $cnt$ 中的每个值加入一个优先队列(大根堆) $pq$ 中。每次从 $pq$ 中取出两个元素 $x$ 和 $y,ドル将它们的值减一,如果减一后的值仍大于 0ドル,ドル则将减一后的值重新加入 $pq$。每次从 $pq$ 中取出两个元素,表示将数组中的两个数对删除,因此数组的长度减少 2ドル$。当 $pq$ 的大小小于 2ドル$ 时,停止删除操作。 + +时间复杂度 $O(n \times \log n),ドル空间复杂度 $O(n)$。其中 $n$ 是数组 $nums$ 的长度。 + + + +### **Python3** + + + +```python +class Solution: + def minLengthAfterRemovals(self, nums: List[int]) -> int: + cnt = Counter(nums) + pq = [-x for x in cnt.values()] + heapify(pq) + ans = len(nums) + while len(pq)> 1: + x, y = -heappop(pq), -heappop(pq) + x -= 1 + y -= 1 + if x> 0: + heappush(pq, -x) + if y> 0: + heappush(pq, -y) + ans -= 2 + return ans +``` + +### **Java** + + + +```java +class Solution { + public int minLengthAfterRemovals(List nums) { + Map cnt = new HashMap(); + for (int x : nums) { + cnt.merge(x, 1, Integer::sum); + } + PriorityQueue pq = new PriorityQueue(Comparator.reverseOrder()); + for (int x : cnt.values()) { + pq.offer(x); + } + int ans = nums.size(); + while (pq.size()> 1) { + int x = pq.poll(); + int y = pq.poll(); + x--; + y--; + if (x> 0) { + pq.offer(x); + } + if (y> 0) { + pq.offer(y); + } + ans -= 2; + } + return ans; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + int minLengthAfterRemovals(vector& nums) { + unordered_map cnt; + for (int x : nums) { + ++cnt[x]; + } + priority_queue pq; + for (auto& [_, v] : cnt) { + pq.push(v); + } + int ans = nums.size(); + while (pq.size()> 1) { + int x = pq.top(); + pq.pop(); + int y = pq.top(); + pq.pop(); + x--; + y--; + if (x> 0) { + pq.push(x); + } + if (y> 0) { + pq.push(y); + } + ans -= 2; + } + return ans; + } +}; +``` + +### **Go** + +```go +func minLengthAfterRemovals(nums []int) int { + cnt := map[int]int{} + for _, x := range nums { + cnt[x]++ + } + h := &hp{} + for _, x := range cnt { + h.push(x) + } + ans := len(nums) + for h.Len()> 1 { + x, y := h.pop(), h.pop() + if x> 1 { + h.push(x - 1) + } + if y> 1 { + h.push(y - 1) + } + ans -= 2 + } + return ans +} + +type hp struct{ sort.IntSlice } + +func (h hp) Less(i, j int) bool { return h.IntSlice[i]> h.IntSlice[j] } +func (h *hp) Push(v any) { h.IntSlice = append(h.IntSlice, v.(int)) } +func (h *hp) Pop() any { + a := h.IntSlice + v := a[len(a)-1] + h.IntSlice = a[:len(a)-1] + return v +} +func (h *hp) push(v int) { heap.Push(h, v) } +func (h *hp) pop() int { return heap.Pop(h).(int) } +``` + +### **TypeScript** + +```ts +function minLengthAfterRemovals(nums: number[]): number { + const cnt: Map = new Map(); + for (const x of nums) { + cnt.set(x, (cnt.get(x) ?? 0) + 1); + } + const pq = new MaxPriorityQueue(); + for (const [_, v] of cnt) { + pq.enqueue(v); + } + let ans = nums.length; + while (pq.size()> 1) { + let x = pq.dequeue().element; + let y = pq.dequeue().element; + if (--x> 0) { + pq.enqueue(x); + } + if (--y> 0) { + pq.enqueue(y); + } + ans -= 2; + } + return ans; +} +``` + +### **...** + +``` + +``` + + diff --git a/solution/2800-2899/2856.Minimum Array Length After Pair Removals/README_EN.md b/solution/2800-2899/2856.Minimum Array Length After Pair Removals/README_EN.md new file mode 100644 index 0000000000000..a1f5e0d862a83 --- /dev/null +++ b/solution/2800-2899/2856.Minimum Array Length After Pair Removals/README_EN.md @@ -0,0 +1,233 @@ +# [2856. Minimum Array Length After Pair Removals](https://leetcode.com/problems/minimum-array-length-after-pair-removals) + +[中文文档](/solution/2800-2899/2856.Minimum%20Array%20Length%20After%20Pair%20Removals/README.md) + +## Description + +

You are given a 0-indexed sorted array of integers nums.

+ +

You can perform the following operation any number of times:

+ +
    +
  • Choose two indices, i and j, where i < j, such that nums[i] < nums[j].
  • +
  • Then, remove the elements at indices i and j from nums. The remaining elements retain their original order, and the array is re-indexed.
  • +
+ +

Return an integer that denotes the minimum length of nums after performing the operation any number of times (including zero).

+ +

Note that nums is sorted in non-decreasing order.

+ + +

Example 1:

+ +
+Input: nums = [1,3,4,9]
+Output: 0
+Explanation: Initially, nums = [1, 3, 4, 9].
+In the first operation, we can choose index 0 and 1 because nums[0] < nums[1] <=> 1 < 3.
+Remove indices 0 and 1, and nums becomes [4, 9].
+For the next operation, we can choose index 0 and 1 because nums[0] < nums[1] <=> 4 < 9.
+Remove indices 0 and 1, and nums becomes an empty array [].
+Hence, the minimum length achievable is 0.
+ +

Example 2:

+ +
+Input: nums = [2,3,6,9]
+Output: 0
+Explanation: Initially, nums = [2, 3, 6, 9]. 
+In the first operation, we can choose index 0 and 2 because nums[0] < nums[2] <=> 2 < 6. 
+Remove indices 0 and 2, and nums becomes [3, 9]. 
+For the next operation, we can choose index 0 and 1 because nums[0] < nums[1] <=> 3 < 9. 
+Remove indices 0 and 1, and nums becomes an empty array []. 
+Hence, the minimum length achievable is 0.
+
+ +

Example 3:

+ +
+Input: nums = [1,1,2]
+Output: 1
+Explanation: Initially, nums = [1, 1, 2].
+In an operation, we can choose index 0 and 2 because nums[0] < nums[2] <=> 1 < 2. 
+Remove indices 0 and 2, and nums becomes [1]. 
+It is no longer possible to perform an operation on the array. 
+Hence, the minimum achievable length is 1. 
+
+ + +

Constraints:

+ +
    +
  • 1 <= nums.length <= 105
  • +
  • 1 <= nums[i] <= 109
  • +
  • nums is sorted in non-decreasing order.
  • +
+ +## Solutions + + + +### **Python3** + +```python +class Solution: + def minLengthAfterRemovals(self, nums: List[int]) -> int: + cnt = Counter(nums) + pq = [-x for x in cnt.values()] + heapify(pq) + ans = len(nums) + while len(pq)> 1: + x, y = -heappop(pq), -heappop(pq) + x -= 1 + y -= 1 + if x> 0: + heappush(pq, -x) + if y> 0: + heappush(pq, -y) + ans -= 2 + return ans +``` + +### **Java** + +```java +class Solution { + public int minLengthAfterRemovals(List nums) { + Map cnt = new HashMap(); + for (int x : nums) { + cnt.merge(x, 1, Integer::sum); + } + PriorityQueue pq = new PriorityQueue(Comparator.reverseOrder()); + for (int x : cnt.values()) { + pq.offer(x); + } + int ans = nums.size(); + while (pq.size()> 1) { + int x = pq.poll(); + int y = pq.poll(); + x--; + y--; + if (x> 0) { + pq.offer(x); + } + if (y> 0) { + pq.offer(y); + } + ans -= 2; + } + return ans; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + int minLengthAfterRemovals(vector& nums) { + unordered_map cnt; + for (int x : nums) { + ++cnt[x]; + } + priority_queue pq; + for (auto& [_, v] : cnt) { + pq.push(v); + } + int ans = nums.size(); + while (pq.size()> 1) { + int x = pq.top(); + pq.pop(); + int y = pq.top(); + pq.pop(); + x--; + y--; + if (x> 0) { + pq.push(x); + } + if (y> 0) { + pq.push(y); + } + ans -= 2; + } + return ans; + } +}; +``` + +### **Go** + +```go +func minLengthAfterRemovals(nums []int) int { + cnt := map[int]int{} + for _, x := range nums { + cnt[x]++ + } + h := &hp{} + for _, x := range cnt { + h.push(x) + } + ans := len(nums) + for h.Len()> 1 { + x, y := h.pop(), h.pop() + if x> 1 { + h.push(x - 1) + } + if y> 1 { + h.push(y - 1) + } + ans -= 2 + } + return ans +} + +type hp struct{ sort.IntSlice } + +func (h hp) Less(i, j int) bool { return h.IntSlice[i]> h.IntSlice[j] } +func (h *hp) Push(v any) { h.IntSlice = append(h.IntSlice, v.(int)) } +func (h *hp) Pop() any { + a := h.IntSlice + v := a[len(a)-1] + h.IntSlice = a[:len(a)-1] + return v +} +func (h *hp) push(v int) { heap.Push(h, v) } +func (h *hp) pop() int { return heap.Pop(h).(int) } +``` + +### **TypeScript** + +```ts +function minLengthAfterRemovals(nums: number[]): number { + const cnt: Map = new Map(); + for (const x of nums) { + cnt.set(x, (cnt.get(x) ?? 0) + 1); + } + const pq = new MaxPriorityQueue(); + for (const [_, v] of cnt) { + pq.enqueue(v); + } + let ans = nums.length; + while (pq.size()> 1) { + let x = pq.dequeue().element; + let y = pq.dequeue().element; + if (--x> 0) { + pq.enqueue(x); + } + if (--y> 0) { + pq.enqueue(y); + } + ans -= 2; + } + return ans; +} +``` + +### **...** + +``` + +``` + + diff --git a/solution/2800-2899/2856.Minimum Array Length After Pair Removals/Solution.cpp b/solution/2800-2899/2856.Minimum Array Length After Pair Removals/Solution.cpp new file mode 100644 index 0000000000000..e53c90dbbffde --- /dev/null +++ b/solution/2800-2899/2856.Minimum Array Length After Pair Removals/Solution.cpp @@ -0,0 +1,30 @@ +class Solution { +public: + int minLengthAfterRemovals(vector& nums) { + unordered_map cnt; + for (int x : nums) { + ++cnt[x]; + } + priority_queue pq; + for (auto& [_, v] : cnt) { + pq.push(v); + } + int ans = nums.size(); + while (pq.size()> 1) { + int x = pq.top(); + pq.pop(); + int y = pq.top(); + pq.pop(); + x--; + y--; + if (x> 0) { + pq.push(x); + } + if (y> 0) { + pq.push(y); + } + ans -= 2; + } + return ans; + } +}; \ No newline at end of file diff --git a/solution/2800-2899/2856.Minimum Array Length After Pair Removals/Solution.go b/solution/2800-2899/2856.Minimum Array Length After Pair Removals/Solution.go new file mode 100644 index 0000000000000..18b5eff60a84f --- /dev/null +++ b/solution/2800-2899/2856.Minimum Array Length After Pair Removals/Solution.go @@ -0,0 +1,35 @@ +func minLengthAfterRemovals(nums []int) int { + cnt := map[int]int{} + for _, x := range nums { + cnt[x]++ + } + h := &hp{} + for _, x := range cnt { + h.push(x) + } + ans := len(nums) + for h.Len()> 1 { + x, y := h.pop(), h.pop() + if x> 1 { + h.push(x - 1) + } + if y> 1 { + h.push(y - 1) + } + ans -= 2 + } + return ans +} + +type hp struct{ sort.IntSlice } + +func (h hp) Less(i, j int) bool { return h.IntSlice[i]> h.IntSlice[j] } +func (h *hp) Push(v any) { h.IntSlice = append(h.IntSlice, v.(int)) } +func (h *hp) Pop() any { + a := h.IntSlice + v := a[len(a)-1] + h.IntSlice = a[:len(a)-1] + return v +} +func (h *hp) push(v int) { heap.Push(h, v) } +func (h *hp) pop() int { return heap.Pop(h).(int) } \ No newline at end of file diff --git a/solution/2800-2899/2856.Minimum Array Length After Pair Removals/Solution.java b/solution/2800-2899/2856.Minimum Array Length After Pair Removals/Solution.java new file mode 100644 index 0000000000000..1e6385cf6aa0b --- /dev/null +++ b/solution/2800-2899/2856.Minimum Array Length After Pair Removals/Solution.java @@ -0,0 +1,27 @@ +class Solution { + public int minLengthAfterRemovals(List nums) { + Map cnt = new HashMap(); + for (int x : nums) { + cnt.merge(x, 1, Integer::sum); + } + PriorityQueue pq = new PriorityQueue(Comparator.reverseOrder()); + for (int x : cnt.values()) { + pq.offer(x); + } + int ans = nums.size(); + while (pq.size()> 1) { + int x = pq.poll(); + int y = pq.poll(); + x--; + y--; + if (x> 0) { + pq.offer(x); + } + if (y> 0) { + pq.offer(y); + } + ans -= 2; + } + return ans; + } +} \ No newline at end of file diff --git a/solution/2800-2899/2856.Minimum Array Length After Pair Removals/Solution.py b/solution/2800-2899/2856.Minimum Array Length After Pair Removals/Solution.py new file mode 100644 index 0000000000000..5c9b4dc8b5037 --- /dev/null +++ b/solution/2800-2899/2856.Minimum Array Length After Pair Removals/Solution.py @@ -0,0 +1,16 @@ +class Solution: + def minLengthAfterRemovals(self, nums: List[int]) -> int: + cnt = Counter(nums) + pq = [-x for x in cnt.values()] + heapify(pq) + ans = len(nums) + while len(pq)> 1: + x, y = -heappop(pq), -heappop(pq) + x -= 1 + y -= 1 + if x> 0: + heappush(pq, -x) + if y> 0: + heappush(pq, -y) + ans -= 2 + return ans diff --git a/solution/2800-2899/2856.Minimum Array Length After Pair Removals/Solution.ts b/solution/2800-2899/2856.Minimum Array Length After Pair Removals/Solution.ts new file mode 100644 index 0000000000000..02d365ead29b2 --- /dev/null +++ b/solution/2800-2899/2856.Minimum Array Length After Pair Removals/Solution.ts @@ -0,0 +1,23 @@ +function minLengthAfterRemovals(nums: number[]): number { + const cnt: Map = new Map(); + for (const x of nums) { + cnt.set(x, (cnt.get(x) ?? 0) + 1); + } + const pq = new MaxPriorityQueue(); + for (const [_, v] of cnt) { + pq.enqueue(v); + } + let ans = nums.length; + while (pq.size()> 1) { + let x = pq.dequeue().element; + let y = pq.dequeue().element; + if (--x> 0) { + pq.enqueue(x); + } + if (--y> 0) { + pq.enqueue(y); + } + ans -= 2; + } + return ans; +} diff --git a/solution/2800-2899/2857.Count Pairs of Points With Distance k/README.md b/solution/2800-2899/2857.Count Pairs of Points With Distance k/README.md new file mode 100644 index 0000000000000..5398f942ea5d0 --- /dev/null +++ b/solution/2800-2899/2857.Count Pairs of Points With Distance k/README.md @@ -0,0 +1,188 @@ +# [2857. 统计距离为 k 的点对](https://leetcode.cn/problems/count-pairs-of-points-with-distance-k) + +[English Version](/solution/2800-2899/2857.Count%20Pairs%20of%20Points%20With%20Distance%20k/README_EN.md) + +## 题目描述 + + + +

给你一个 二维 整数数组 coordinates 和一个整数 k ,其中 coordinates[i] = [xi, yi] 是第 i 个点在二维平面里的坐标。

+ +

我们定义两个点 (x1, y1)(x2, y2)距离(x1 XOR x2) + (y1 XOR y2) ,XOR 指的是按位异或运算。

+ +

请你返回满足i < j且点i和点j之间距离为k 的点对数目。

+ + + +

示例 1:

+ +
+输入:coordinates = [[1,2],[4,2],[1,3],[5,2]], k = 5
+输出:2
+解释:以下点对距离为 k :
+- (0, 1):(1 XOR 4) + (2 XOR 2) = 5 。
+- (2, 3):(1 XOR 5) + (3 XOR 2) = 5 。
+
+ +

示例 2:

+ +
+输入:coordinates = [[1,3],[1,3],[1,3],[1,3],[1,3]], k = 0
+输出:10
+解释:任何两个点之间的距离都为 0 ,所以总共有 10 组点对。
+
+ + + +

提示:

+ +
    +
  • 2 <= coordinates.length <= 50000
  • +
  • 0 <= xi, yi <= 106
  • +
  • 0 <= k <= 100
  • +
+ +## 解法 + + + +**方法一:哈希表 + 枚举** + +我们可以用一个哈希表 $cnt$ 统计数组 $coordinates$ 中每个点出现的次数。 + +接下来,我们枚举数组 $coordinates$ 中的每个点 $(x_2, y_2),ドル由于 $k$ 的取值范围为 $[0, 100],ドル而 $x_1 \oplus x_2$ 或 $y_1 \oplus y_2$ 的结果一定大于等于 0ドル,ドル因此我们可以在 $[0,..k]$ 范围内枚举 $x_1 \oplus x_2$ 的结果 $a,ドル那么 $y_1 \oplus y_2$ 的结果就是 $b = k - a$。这样一来,我们就可以计算出 $x_1$ 和 $y_1$ 的值,将 $(x_1, y_1)$ 出现的次数累加到答案中。 + +时间复杂度 $O(n \times k),ドル空间复杂度 $O(n)$。其中 $n$ 是数组 $coordinates$ 的长度。 + + + +### **Python3** + + + +```python +class Solution: + def countPairs(self, coordinates: List[List[int]], k: int) -> int: + cnt = Counter() + ans = 0 + for x2, y2 in coordinates: + for a in range(k + 1): + b = k - a + x1, y1 = a ^ x2, b ^ y2 + ans += cnt[(x1, y1)] + cnt[(x2, y2)] += 1 + return ans +``` + +### **Java** + + + +```java +class Solution { + public int countPairs(List> coordinates, int k) { + Map, Integer> cnt = new HashMap(); + int ans = 0; + for (var c : coordinates) { + int x2 = c.get(0), y2 = c.get(1); + for (int a = 0; a <= k; ++a) { + int b = k - a; + int x1 = a ^ x2, y1 = b ^ y2; + ans += cnt.getOrDefault(List.of(x1, y1), 0); + } + cnt.merge(c, 1, Integer::sum); + } + return ans; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + int countPairs(vector>& coordinates, int k) { + map, int> cnt; + int ans = 0; + for (auto& c : coordinates) { + int x2 = c[0], y2 = c[1]; + for (int a = 0; a <= k; ++a) { + int b = k - a; + int x1 = a ^ x2, y1 = b ^ y2; + ans += cnt[{x1, y1}]; + } + ++cnt[{x2, y2}]; + } + return ans; + } +}; +``` + +```cpp +class Solution { +public: + int countPairs(vector>& coordinates, int k) { + unordered_map cnt; + auto f = [](int x, int y) { + return x * 1000000L + y; + }; + int ans = 0; + for (auto& c : coordinates) { + int x2 = c[0], y2 = c[1]; + for (int a = 0; a <= k; ++a) { + int b = k - a; + int x1 = a ^ x2, y1 = b ^ y2; + ans += cnt[f(x1, y1)]; + } + ++cnt[f(x2, y2)]; + } + return ans; + } +}; +``` + +### **Go** + +```go +func countPairs(coordinates [][]int, k int) (ans int) { + cnt := map[[2]int]int{} + for _, c := range coordinates { + x2, y2 := c[0], c[1] + for a := 0; a <= k; a++ { + b := k - a + x1, y1 := a^x2, b^y2 + ans += cnt[[2]int{x1, y1}] + } + cnt[[2]int{x2, y2}]++ + } + return +} +``` + +### **TypeScript** + +```ts +function countPairs(coordinates: number[][], k: number): number { + const cnt: Map = new Map(); + const f = (x: number, y: number): number => x * 1000000 + y; + let ans = 0; + for (const [x2, y2] of coordinates) { + for (let a = 0; a <= k; ++a) { + const b = k - a; + const [x1, y1] = [a ^ x2, b ^ y2]; + ans += cnt.get(f(x1, y1)) ?? 0; + } + cnt.set(f(x2, y2), (cnt.get(f(x2, y2)) ?? 0) + 1); + } + return ans; +} +``` + +### **...** + +``` + +``` + + diff --git a/solution/2800-2899/2857.Count Pairs of Points With Distance k/README_EN.md b/solution/2800-2899/2857.Count Pairs of Points With Distance k/README_EN.md new file mode 100644 index 0000000000000..0fa47fac77eb3 --- /dev/null +++ b/solution/2800-2899/2857.Count Pairs of Points With Distance k/README_EN.md @@ -0,0 +1,170 @@ +# [2857. Count Pairs of Points With Distance k](https://leetcode.com/problems/count-pairs-of-points-with-distance-k) + +[中文文档](/solution/2800-2899/2857.Count%20Pairs%20of%20Points%20With%20Distance%20k/README.md) + +## Description + +

You are given a 2D integer array coordinates and an integer k, where coordinates[i] = [xi, yi] are the coordinates of the ith point in a 2D plane.

+ +

We define the distance between two points (x1, y1) and (x2, y2) as (x1 XOR x2) + (y1 XOR y2) where XOR is the bitwise XOR operation.

+ +

Return the number of pairs (i, j) such that i < j and the distance between points i and j is equal to k.

+ + +

Example 1:

+ +
+Input: coordinates = [[1,2],[4,2],[1,3],[5,2]], k = 5
+Output: 2
+Explanation: We can choose the following pairs:
+- (0,1): Because we have (1 XOR 4) + (2 XOR 2) = 5.
+- (2,3): Because we have (1 XOR 5) + (3 XOR 2) = 5.
+
+ +

Example 2:

+ +
+Input: coordinates = [[1,3],[1,3],[1,3],[1,3],[1,3]], k = 0
+Output: 10
+Explanation: Any two chosen pairs will have a distance of 0. There are 10 ways to choose two pairs.
+
+ + +

Constraints:

+ +
    +
  • 2 <= coordinates.length <= 50000
  • +
  • 0 <= xi, yi <= 106
  • +
  • 0 <= k <= 100
  • +
+ +## Solutions + + + +### **Python3** + +```python +class Solution: + def countPairs(self, coordinates: List[List[int]], k: int) -> int: + cnt = Counter() + ans = 0 + for x2, y2 in coordinates: + for a in range(k + 1): + b = k - a + x1, y1 = a ^ x2, b ^ y2 + ans += cnt[(x1, y1)] + cnt[(x2, y2)] += 1 + return ans +``` + +### **Java** + +```java +class Solution { + public int countPairs(List> coordinates, int k) { + Map, Integer> cnt = new HashMap(); + int ans = 0; + for (var c : coordinates) { + int x2 = c.get(0), y2 = c.get(1); + for (int a = 0; a <= k; ++a) { + int b = k - a; + int x1 = a ^ x2, y1 = b ^ y2; + ans += cnt.getOrDefault(List.of(x1, y1), 0); + } + cnt.merge(c, 1, Integer::sum); + } + return ans; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + int countPairs(vector>& coordinates, int k) { + map, int> cnt; + int ans = 0; + for (auto& c : coordinates) { + int x2 = c[0], y2 = c[1]; + for (int a = 0; a <= k; ++a) { + int b = k - a; + int x1 = a ^ x2, y1 = b ^ y2; + ans += cnt[{x1, y1}]; + } + ++cnt[{x2, y2}]; + } + return ans; + } +}; +``` + +```cpp +class Solution { +public: + int countPairs(vector>& coordinates, int k) { + unordered_map cnt; + auto f = [](int x, int y) { + return x * 1000000L + y; + }; + int ans = 0; + for (auto& c : coordinates) { + int x2 = c[0], y2 = c[1]; + for (int a = 0; a <= k; ++a) { + int b = k - a; + int x1 = a ^ x2, y1 = b ^ y2; + ans += cnt[f(x1, y1)]; + } + ++cnt[f(x2, y2)]; + } + return ans; + } +}; +``` + +### **Go** + +```go +func countPairs(coordinates [][]int, k int) (ans int) { + cnt := map[[2]int]int{} + for _, c := range coordinates { + x2, y2 := c[0], c[1] + for a := 0; a <= k; a++ { + b := k - a + x1, y1 := a^x2, b^y2 + ans += cnt[[2]int{x1, y1}] + } + cnt[[2]int{x2, y2}]++ + } + return +} +``` + +### **TypeScript** + +```ts +function countPairs(coordinates: number[][], k: number): number { + const cnt: Map = new Map(); + const f = (x: number, y: number): number => x * 1000000 + y; + let ans = 0; + for (const [x2, y2] of coordinates) { + for (let a = 0; a <= k; ++a) { + const b = k - a; + const [x1, y1] = [a ^ x2, b ^ y2]; + ans += cnt.get(f(x1, y1)) ?? 0; + } + cnt.set(f(x2, y2), (cnt.get(f(x2, y2)) ?? 0) + 1); + } + return ans; +} +``` + +### **...** + +``` + +``` + + diff --git a/solution/2800-2899/2857.Count Pairs of Points With Distance k/Solution.cpp b/solution/2800-2899/2857.Count Pairs of Points With Distance k/Solution.cpp new file mode 100644 index 0000000000000..0fee7d0432a81 --- /dev/null +++ b/solution/2800-2899/2857.Count Pairs of Points With Distance k/Solution.cpp @@ -0,0 +1,20 @@ +class Solution { +public: + int countPairs(vector>& coordinates, int k) { + unordered_map cnt; + auto f = [](int x, int y) { + return x * 1000000L + y; + }; + int ans = 0; + for (auto& c : coordinates) { + int x2 = c[0], y2 = c[1]; + for (int a = 0; a <= k; ++a) { + int b = k - a; + int x1 = a ^ x2, y1 = b ^ y2; + ans += cnt[f(x1, y1)]; + } + ++cnt[f(x2, y2)]; + } + return ans; + } +}; \ No newline at end of file diff --git a/solution/2800-2899/2857.Count Pairs of Points With Distance k/Solution.java b/solution/2800-2899/2857.Count Pairs of Points With Distance k/Solution.java new file mode 100644 index 0000000000000..8de215445c58d --- /dev/null +++ b/solution/2800-2899/2857.Count Pairs of Points With Distance k/Solution.java @@ -0,0 +1,16 @@ +class Solution { + public int countPairs(List> coordinates, int k) { + Map, Integer> cnt = new HashMap(); + int ans = 0; + for (var c : coordinates) { + int x2 = c.get(0), y2 = c.get(1); + for (int a = 0; a <= k; ++a) { + int b = k - a; + int x1 = a ^ x2, y1 = b ^ y2; + ans += cnt.getOrDefault(List.of(x1, y1), 0); + } + cnt.merge(c, 1, Integer::sum); + } + return ans; + } +} \ No newline at end of file diff --git a/solution/2800-2899/2857.Count Pairs of Points With Distance k/Solution.py b/solution/2800-2899/2857.Count Pairs of Points With Distance k/Solution.py new file mode 100644 index 0000000000000..5b114a5ace1b4 --- /dev/null +++ b/solution/2800-2899/2857.Count Pairs of Points With Distance k/Solution.py @@ -0,0 +1,11 @@ +class Solution: + def countPairs(self, coordinates: List[List[int]], k: int) -> int: + cnt = Counter() + ans = 0 + for x2, y2 in coordinates: + for a in range(k + 1): + b = k - a + x1, y1 = a ^ x2, b ^ y2 + ans += cnt[(x1, y1)] + cnt[(x2, y2)] += 1 + return ans diff --git a/solution/2800-2899/2857.Count Pairs of Points With Distance k/Solution.ts b/solution/2800-2899/2857.Count Pairs of Points With Distance k/Solution.ts new file mode 100644 index 0000000000000..714530cbf20f6 --- /dev/null +++ b/solution/2800-2899/2857.Count Pairs of Points With Distance k/Solution.ts @@ -0,0 +1,14 @@ +function countPairs(coordinates: number[][], k: number): number { + const cnt: Map = new Map(); + const f = (x: number, y: number): number => x * 1000000 + y; + let ans = 0; + for (const [x2, y2] of coordinates) { + for (let a = 0; a <= k; ++a) { + const b = k - a; + const [x1, y1] = [a ^ x2, b ^ y2]; + ans += cnt.get(f(x1, y1)) ?? 0; + } + cnt.set(f(x2, y2), (cnt.get(f(x2, y2)) ?? 0) + 1); + } + return ans; +} diff --git a/solution/2800-2899/2857.Count Pairs of Points With Distance k/Soution.go b/solution/2800-2899/2857.Count Pairs of Points With Distance k/Soution.go new file mode 100644 index 0000000000000..0cb2171551372 --- /dev/null +++ b/solution/2800-2899/2857.Count Pairs of Points With Distance k/Soution.go @@ -0,0 +1,13 @@ +func countPairs(coordinates [][]int, k int) (ans int) { + cnt := map[[2]int]int{} + for _, c := range coordinates { + x2, y2 := c[0], c[1] + for a := 0; a <= k; a++ { + b := k - a + x1, y1 := a^x2, b^y2 + ans += cnt[[2]int{x1, y1}] + } + cnt[[2]int{x2, y2}]++ + } + return +} \ No newline at end of file diff --git a/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/README.md b/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/README.md new file mode 100644 index 0000000000000..35fb9ffbe7b4f --- /dev/null +++ b/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/README.md @@ -0,0 +1,268 @@ +# [2858. 可以到达每一个节点的最少边反转次数](https://leetcode.cn/problems/minimum-edge-reversals-so-every-node-is-reachable) + +[English Version](/solution/2800-2899/2858.Minimum%20Edge%20Reversals%20So%20Every%20Node%20Is%20Reachable/README_EN.md) + +## 题目描述 + + + +

给你一个 n 个点的 简单有向图 (没有重复边的有向图),节点编号为 0n - 1 。如果这些边是双向边,那么这个图形成一棵

+ +

给你一个整数 n 和一个 二维 整数数组 edges ,其中 edges[i] = [ui, vi] 表示从节点 ui 到节点 vi 有一条 有向边

+ +

边反转 指的是将一条边的方向反转,也就是说一条从节点 ui 到节点 vi 的边会变为一条从节点 vi 到节点 ui 的边。

+ +

对于范围 [0, n - 1] 中的每一个节点 i ,你的任务是分别 独立 计算 最少 需要多少次 边反转 ,从节点 i 出发经过 一系列有向边 ,可以到达所有的节点。

+ +

请你返回一个长度为 n 的整数数组answer,其中answer[i]表示从节点 i 出发,可以到达所有节点的 最少边反转 次数。

+ + + +

示例 1:

+ + + +
+输入:n = 4, edges = [[2,0],[2,1],[1,3]]
+输出:[1,1,0,2]
+解释:上图表示了与输入对应的简单有向图。
+对于节点 0 :反转 [2,0] ,从节点 0 出发可以到达所有节点。
+所以 answer[0] = 1 。
+对于节点 1 :反转 [2,1] ,从节点 1 出发可以到达所有节点。
+所以 answer[1] = 1 。
+对于节点 2 :不需要反转就可以从节点 2 出发到达所有节点。
+所以 answer[2] = 0 。
+对于节点 3 :反转 [1,3] 和 [2,1] ,从节点 3 出发可以到达所有节点。
+所以 answer[3] = 2 。
+
+ +

示例 2:

+ + + +
+输入:n = 3, edges = [[1,2],[2,0]]
+输出:[2,0,1]
+解释:上图表示了与输入对应的简单有向图。
+对于节点 0 :反转 [2,0] 和 [1,2] ,从节点 0 出发可以到达所有节点。
+所以 answer[0] = 2 。
+对于节点 1 :不需要反转就可以从节点 2 出发到达所有节点。
+所以 answer[1] = 0 。
+对于节点 2 :反转 [1,2] ,从节点 2 出发可以到达所有节点。
+所以 answer[2] = 1 。
+
+ + + +

提示:

+ +
    +
  • 2 <= n <= 105
  • +
  • edges.length == n - 1
  • +
  • edges[i].length == 2
  • +
  • 0 <= ui == edges[i][0] < n
  • +
  • 0 <= vi == edges[i][1] < n
  • +
  • ui != vi
  • +
  • 输入保证如果边是双向边,可以得到一棵树。
  • +
+ +## 解法 + + + +**方法一:树形 DP** + +时间复杂度 $O(n),ドル空间复杂度 $O(n)$。 + + + +### **Python3** + + + +```python +class Solution: + def minEdgeReversals(self, n: int, edges: List[List[int]]) -> List[int]: + ans = [0] * n + g = [[] for _ in range(n)] + for x, y in edges: + g[x].append((y, 1)) + g[y].append((x, -1)) + + def dfs(i: int, fa: int): + for j, k in g[i]: + if j != fa: + ans[0] += int(k < 0) + dfs(j, i) + + dfs(0, -1) + + def dfs2(i: int, fa: int): + for j, k in g[i]: + if j != fa: + ans[j] = ans[i] + k + dfs2(j, i) + + dfs2(0, -1) + return ans +``` + +### **Java** + + + +```java +class Solution { + private List[] g; + private int[] ans; + + public int[] minEdgeReversals(int n, int[][] edges) { + ans = new int[n]; + g = new List[n]; + Arrays.setAll(g, i -> new ArrayList()); + for (var e : edges) { + int x = e[0], y = e[1]; + g[x].add(new int[] {y, 1}); + g[y].add(new int[] {x, -1}); + } + dfs(0, -1); + dfs2(0, -1); + return ans; + } + + private void dfs(int i, int fa) { + for (var ne : g[i]) { + int j = ne[0], k = ne[1]; + if (j != fa) { + ans[0] += k < 0 ? 1 : 0; + dfs(j, i); + } + } + } + + private void dfs2(int i, int fa) { + for (var ne : g[i]) { + int j = ne[0], k = ne[1]; + if (j != fa) { + ans[j] = ans[i] + k; + dfs2(j, i); + } + } + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + vector minEdgeReversals(int n, vector>& edges) { + vector> g[n]; + vector ans(n); + for (auto& e : edges) { + int x = e[0], y = e[1]; + g[x].emplace_back(y, 1); + g[y].emplace_back(x, -1); + } + function dfs = [&](int i, int fa) { + for (auto& [j, k] : g[i]) { + if (j != fa) { + ans[0] += k < 0; + dfs(j, i); + } + } + }; + function dfs2 = [&](int i, int fa) { + for (auto& [j, k] : g[i]) { + if (j != fa) { + ans[j] = ans[i] + k; + dfs2(j, i); + } + } + }; + dfs(0, -1); + dfs2(0, -1); + return ans; + } +}; +``` + +### **Go** + +```go +func minEdgeReversals(n int, edges [][]int) []int { + g := make([][][2]int, n) + for _, e := range edges { + x, y := e[0], e[1] + g[x] = append(g[x], [2]int{y, 1}) + g[y] = append(g[y], [2]int{x, -1}) + } + ans := make([]int, n) + var dfs func(int, int) + var dfs2 func(int, int) + dfs = func(i, fa int) { + for _, ne := range g[i] { + j, k := ne[0], ne[1] + if j != fa { + if k < 0 { + ans[0]++ + } + dfs(j, i) + } + } + } + dfs2 = func(i, fa int) { + for _, ne := range g[i] { + j, k := ne[0], ne[1] + if j != fa { + ans[j] = ans[i] + k + dfs2(j, i) + } + } + } + dfs(0, -1) + dfs2(0, -1) + return ans +} +``` + +### **TypeScript** + +```ts +function minEdgeReversals(n: number, edges: number[][]): number[] { + const g: number[][][] = Array.from({ length: n }, () => []); + for (const [x, y] of edges) { + g[x].push([y, 1]); + g[y].push([x, -1]); + } + const ans: number[] = Array(n).fill(0); + const dfs = (i: number, fa: number) => { + for (const [j, k] of g[i]) { + if (j !== fa) { + ans[0] += k < 0 ? 1 : 0; + dfs(j, i); + } + } + }; + const dfs2 = (i: number, fa: number) => { + for (const [j, k] of g[i]) { + if (j !== fa) { + ans[j] = ans[i] + k; + dfs2(j, i); + } + } + }; + dfs(0, -1); + dfs2(0, -1); + return ans; +} +``` + +### **...** + +``` + +``` + + diff --git a/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/README_EN.md b/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/README_EN.md new file mode 100644 index 0000000000000..99a0dd9310d54 --- /dev/null +++ b/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/README_EN.md @@ -0,0 +1,254 @@ +# [2858. Minimum Edge Reversals So Every Node Is Reachable](https://leetcode.com/problems/minimum-edge-reversals-so-every-node-is-reachable) + +[中文文档](/solution/2800-2899/2858.Minimum%20Edge%20Reversals%20So%20Every%20Node%20Is%20Reachable/README.md) + +## Description + +

There is a simple directed graph with n nodes labeled from 0 to n - 1. The graph would form a tree if its edges were bi-directional.

+ +

You are given an integer n and a 2D integer array edges, where edges[i] = [ui, vi] represents a directed edge going from node ui to node vi.

+ +

An edge reversal changes the direction of an edge, i.e., a directed edge going from node ui to node vi becomes a directed edge going from node vi to node ui.

+ +

For every node i in the range [0, n - 1], your task is to independently calculate the minimum number of edge reversals required so it is possible to reach any other node starting from node i through a sequence of directed edges.

+ +

Return an integer array answer, where answer[i] is the minimum number of edge reversals required so it is possible to reach any other node starting from node i through a sequence of directed edges.

+ + +

Example 1:

+ + + +
+Input: n = 4, edges = [[2,0],[2,1],[1,3]]
+Output: [1,1,0,2]
+Explanation: The image above shows the graph formed by the edges.
+For node 0: after reversing the edge [2,0], it is possible to reach any other node starting from node 0.
+So, answer[0] = 1.
+For node 1: after reversing the edge [2,1], it is possible to reach any other node starting from node 1.
+So, answer[1] = 1.
+For node 2: it is already possible to reach any other node starting from node 2.
+So, answer[2] = 0.
+For node 3: after reversing the edges [1,3] and [2,1], it is possible to reach any other node starting from node 3.
+So, answer[3] = 2.
+
+ +

Example 2:

+ + + +
+Input: n = 3, edges = [[1,2],[2,0]]
+Output: [2,0,1]
+Explanation: The image above shows the graph formed by the edges.
+For node 0: after reversing the edges [2,0] and [1,2], it is possible to reach any other node starting from node 0.
+So, answer[0] = 2.
+For node 1: it is already possible to reach any other node starting from node 1.
+So, answer[1] = 0.
+For node 2: after reversing the edge [1, 2], it is possible to reach any other node starting from node 2.
+So, answer[2] = 1.
+
+ + +

Constraints:

+ +
    +
  • 2 <= n <= 105
  • +
  • edges.length == n - 1
  • +
  • edges[i].length == 2
  • +
  • 0 <= ui == edges[i][0] < n
  • +
  • 0 <= vi == edges[i][1] < n
  • +
  • ui != vi
  • +
  • The input is generated such that if the edges were bi-directional, the graph would be a tree.
  • +
+ +## Solutions + + + +### **Python3** + +```python +class Solution: + def minEdgeReversals(self, n: int, edges: List[List[int]]) -> List[int]: + ans = [0] * n + g = [[] for _ in range(n)] + for x, y in edges: + g[x].append((y, 1)) + g[y].append((x, -1)) + + def dfs(i: int, fa: int): + for j, k in g[i]: + if j != fa: + ans[0] += int(k < 0) + dfs(j, i) + + dfs(0, -1) + + def dfs2(i: int, fa: int): + for j, k in g[i]: + if j != fa: + ans[j] = ans[i] + k + dfs2(j, i) + + dfs2(0, -1) + return ans +``` + +### **Java** + +```java +class Solution { + private List[] g; + private int[] ans; + + public int[] minEdgeReversals(int n, int[][] edges) { + ans = new int[n]; + g = new List[n]; + Arrays.setAll(g, i -> new ArrayList()); + for (var e : edges) { + int x = e[0], y = e[1]; + g[x].add(new int[] {y, 1}); + g[y].add(new int[] {x, -1}); + } + dfs(0, -1); + dfs2(0, -1); + return ans; + } + + private void dfs(int i, int fa) { + for (var ne : g[i]) { + int j = ne[0], k = ne[1]; + if (j != fa) { + ans[0] += k < 0 ? 1 : 0; + dfs(j, i); + } + } + } + + private void dfs2(int i, int fa) { + for (var ne : g[i]) { + int j = ne[0], k = ne[1]; + if (j != fa) { + ans[j] = ans[i] + k; + dfs2(j, i); + } + } + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + vector minEdgeReversals(int n, vector>& edges) { + vector> g[n]; + vector ans(n); + for (auto& e : edges) { + int x = e[0], y = e[1]; + g[x].emplace_back(y, 1); + g[y].emplace_back(x, -1); + } + function dfs = [&](int i, int fa) { + for (auto& [j, k] : g[i]) { + if (j != fa) { + ans[0] += k < 0; + dfs(j, i); + } + } + }; + function dfs2 = [&](int i, int fa) { + for (auto& [j, k] : g[i]) { + if (j != fa) { + ans[j] = ans[i] + k; + dfs2(j, i); + } + } + }; + dfs(0, -1); + dfs2(0, -1); + return ans; + } +}; +``` + +### **Go** + +```go +func minEdgeReversals(n int, edges [][]int) []int { + g := make([][][2]int, n) + for _, e := range edges { + x, y := e[0], e[1] + g[x] = append(g[x], [2]int{y, 1}) + g[y] = append(g[y], [2]int{x, -1}) + } + ans := make([]int, n) + var dfs func(int, int) + var dfs2 func(int, int) + dfs = func(i, fa int) { + for _, ne := range g[i] { + j, k := ne[0], ne[1] + if j != fa { + if k < 0 { + ans[0]++ + } + dfs(j, i) + } + } + } + dfs2 = func(i, fa int) { + for _, ne := range g[i] { + j, k := ne[0], ne[1] + if j != fa { + ans[j] = ans[i] + k + dfs2(j, i) + } + } + } + dfs(0, -1) + dfs2(0, -1) + return ans +} +``` + +### **TypeScript** + +```ts +function minEdgeReversals(n: number, edges: number[][]): number[] { + const g: number[][][] = Array.from({ length: n }, () => []); + for (const [x, y] of edges) { + g[x].push([y, 1]); + g[y].push([x, -1]); + } + const ans: number[] = Array(n).fill(0); + const dfs = (i: number, fa: number) => { + for (const [j, k] of g[i]) { + if (j !== fa) { + ans[0] += k < 0 ? 1 : 0; + dfs(j, i); + } + } + }; + const dfs2 = (i: number, fa: number) => { + for (const [j, k] of g[i]) { + if (j !== fa) { + ans[j] = ans[i] + k; + dfs2(j, i); + } + } + }; + dfs(0, -1); + dfs2(0, -1); + return ans; +} +``` + +### **...** + +``` + +``` + + diff --git a/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/Solution.cpp b/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/Solution.cpp new file mode 100644 index 0000000000000..4ce382baef59a --- /dev/null +++ b/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/Solution.cpp @@ -0,0 +1,31 @@ +class Solution { +public: + vector minEdgeReversals(int n, vector>& edges) { + vector> g[n]; + vector ans(n); + for (auto& e : edges) { + int x = e[0], y = e[1]; + g[x].emplace_back(y, 1); + g[y].emplace_back(x, -1); + } + function dfs = [&](int i, int fa) { + for (auto& [j, k] : g[i]) { + if (j != fa) { + ans[0] += k < 0; + dfs(j, i); + } + } + }; + function dfs2 = [&](int i, int fa) { + for (auto& [j, k] : g[i]) { + if (j != fa) { + ans[j] = ans[i] + k; + dfs2(j, i); + } + } + }; + dfs(0, -1); + dfs2(0, -1); + return ans; + } +}; \ No newline at end of file diff --git a/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/Solution.go b/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/Solution.go new file mode 100644 index 0000000000000..b9fa738f376f1 --- /dev/null +++ b/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/Solution.go @@ -0,0 +1,34 @@ +func minEdgeReversals(n int, edges [][]int) []int { + g := make([][][2]int, n) + for _, e := range edges { + x, y := e[0], e[1] + g[x] = append(g[x], [2]int{y, 1}) + g[y] = append(g[y], [2]int{x, -1}) + } + ans := make([]int, n) + var dfs func(int, int) + var dfs2 func(int, int) + dfs = func(i, fa int) { + for _, ne := range g[i] { + j, k := ne[0], ne[1] + if j != fa { + if k < 0 { + ans[0]++ + } + dfs(j, i) + } + } + } + dfs2 = func(i, fa int) { + for _, ne := range g[i] { + j, k := ne[0], ne[1] + if j != fa { + ans[j] = ans[i] + k + dfs2(j, i) + } + } + } + dfs(0, -1) + dfs2(0, -1) + return ans +} \ No newline at end of file diff --git a/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/Solution.java b/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/Solution.java new file mode 100644 index 0000000000000..5c4ba99ce072a --- /dev/null +++ b/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/Solution.java @@ -0,0 +1,38 @@ +class Solution { + private List[] g; + private int[] ans; + + public int[] minEdgeReversals(int n, int[][] edges) { + ans = new int[n]; + g = new List[n]; + Arrays.setAll(g, i -> new ArrayList()); + for (var e : edges) { + int x = e[0], y = e[1]; + g[x].add(new int[] {y, 1}); + g[y].add(new int[] {x, -1}); + } + dfs(0, -1); + dfs2(0, -1); + return ans; + } + + private void dfs(int i, int fa) { + for (var ne : g[i]) { + int j = ne[0], k = ne[1]; + if (j != fa) { + ans[0] += k < 0 ? 1 : 0; + dfs(j, i); + } + } + } + + private void dfs2(int i, int fa) { + for (var ne : g[i]) { + int j = ne[0], k = ne[1]; + if (j != fa) { + ans[j] = ans[i] + k; + dfs2(j, i); + } + } + } +} \ No newline at end of file diff --git a/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/Solution.py b/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/Solution.py new file mode 100644 index 0000000000000..fe04256d8155c --- /dev/null +++ b/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/Solution.py @@ -0,0 +1,24 @@ +class Solution: + def minEdgeReversals(self, n: int, edges: List[List[int]]) -> List[int]: + ans = [0] * n + g = [[] for _ in range(n)] + for x, y in edges: + g[x].append((y, 1)) + g[y].append((x, -1)) + + def dfs(i: int, fa: int): + for j, k in g[i]: + if j != fa: + ans[0] += int(k < 0) + dfs(j, i) + + dfs(0, -1) + + def dfs2(i: int, fa: int): + for j, k in g[i]: + if j != fa: + ans[j] = ans[i] + k + dfs2(j, i) + + dfs2(0, -1) + return ans diff --git a/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/Solution.ts b/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/Solution.ts new file mode 100644 index 0000000000000..b28dffa38dfc4 --- /dev/null +++ b/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/Solution.ts @@ -0,0 +1,27 @@ +function minEdgeReversals(n: number, edges: number[][]): number[] { + const g: number[][][] = Array.from({ length: n }, () => []); + for (const [x, y] of edges) { + g[x].push([y, 1]); + g[y].push([x, -1]); + } + const ans: number[] = Array(n).fill(0); + const dfs = (i: number, fa: number) => { + for (const [j, k] of g[i]) { + if (j !== fa) { + ans[0] += k < 0 ? 1 : 0; + dfs(j, i); + } + } + }; + const dfs2 = (i: number, fa: number) => { + for (const [j, k] of g[i]) { + if (j !== fa) { + ans[j] = ans[i] + k; + dfs2(j, i); + } + } + }; + dfs(0, -1); + dfs2(0, -1); + return ans; +} diff --git a/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/images/image-20230826221104-3.png b/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/images/image-20230826221104-3.png new file mode 100644 index 0000000000000..dd782e59f04a4 Binary files /dev/null and b/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/images/image-20230826221104-3.png differ diff --git a/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/images/image-20230826225541-2.png b/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/images/image-20230826225541-2.png new file mode 100644 index 0000000000000..49253a0c475af Binary files /dev/null and b/solution/2800-2899/2858.Minimum Edge Reversals So Every Node Is Reachable/images/image-20230826225541-2.png differ diff --git a/solution/CONTEST_README.md b/solution/CONTEST_README.md index b031664fa8eba..c0c2988da72ce 100644 --- a/solution/CONTEST_README.md +++ b/solution/CONTEST_README.md @@ -22,6 +22,13 @@ ## 往期竞赛 +#### 第 113 场双周赛(2023年09月16日 22:30, 90 分钟) 参赛人数 3028 + +- [2855. 使数组成为递增数组的最少右移次数](/solution/2800-2899/2855.Minimum%20Right%20Shifts%20to%20Sort%20the%20Array/README.md) +- [2856. 删除数对后的最小数组长度](/solution/2800-2899/2856.Minimum%20Array%20Length%20After%20Pair%20Removals/README.md) +- [2857. 统计距离为 k 的点对](/solution/2800-2899/2857.Count%20Pairs%20of%20Points%20With%20Distance%20k/README.md) +- [2858. 可以到达每一个节点的最少边反转次数](/solution/2800-2899/2858.Minimum%20Edge%20Reversals%20So%20Every%20Node%20Is%20Reachable/README.md) + #### 第 362 场周赛(2023年09月10日 10:30, 90 分钟) 参赛人数 4800 - [2848. 与车相交的点](/solution/2800-2899/2848.Points%20That%20Intersect%20With%20Cars/README.md) diff --git a/solution/CONTEST_README_EN.md b/solution/CONTEST_README_EN.md index df58424c8a953..7d011814c92c7 100644 --- a/solution/CONTEST_README_EN.md +++ b/solution/CONTEST_README_EN.md @@ -25,6 +25,13 @@ Get your rating changes right after the completion of LeetCode contests, https:/ ## Past Contests +#### Biweekly Contest 113 + +- [2855. Minimum Right Shifts to Sort the Array](/solution/2800-2899/2855.Minimum%20Right%20Shifts%20to%20Sort%20the%20Array/README_EN.md) +- [2856. Minimum Array Length After Pair Removals](/solution/2800-2899/2856.Minimum%20Array%20Length%20After%20Pair%20Removals/README_EN.md) +- [2857. Count Pairs of Points With Distance k](/solution/2800-2899/2857.Count%20Pairs%20of%20Points%20With%20Distance%20k/README_EN.md) +- [2858. Minimum Edge Reversals So Every Node Is Reachable](/solution/2800-2899/2858.Minimum%20Edge%20Reversals%20So%20Every%20Node%20Is%20Reachable/README_EN.md) + #### Weekly Contest 362 - [2848. Points That Intersect With Cars](/solution/2800-2899/2848.Points%20That%20Intersect%20With%20Cars/README_EN.md) diff --git a/solution/README.md b/solution/README.md index ed178e648a86b..e65182ff5a604 100644 --- a/solution/README.md +++ b/solution/README.md @@ -2865,6 +2865,10 @@ | 2852 | [Sum of Remoteness of All Cells](/solution/2800-2899/2852.Sum%20of%20Remoteness%20of%20All%20Cells/README.md) | | 中等 | 🔒 | | 2853 | [Highest Salaries Difference](/solution/2800-2899/2853.Highest%20Salaries%20Difference/README.md) | | 简单 | 🔒 | | 2854 | [Rolling Average Steps](/solution/2800-2899/2854.Rolling%20Average%20Steps/README.md) | | 中等 | 🔒 | +| 2855 | [使数组成为递增数组的最少右移次数](/solution/2800-2899/2855.Minimum%20Right%20Shifts%20to%20Sort%20the%20Array/README.md) | | 简单 | 第 113 场双周赛 | +| 2856 | [删除数对后的最小数组长度](/solution/2800-2899/2856.Minimum%20Array%20Length%20After%20Pair%20Removals/README.md) | | 中等 | 第 113 场双周赛 | +| 2857 | [统计距离为 k 的点对](/solution/2800-2899/2857.Count%20Pairs%20of%20Points%20With%20Distance%20k/README.md) | | 中等 | 第 113 场双周赛 | +| 2858 | [可以到达每一个节点的最少边反转次数](/solution/2800-2899/2858.Minimum%20Edge%20Reversals%20So%20Every%20Node%20Is%20Reachable/README.md) | | 困难 | 第 113 场双周赛 | ## 版权 diff --git a/solution/README_EN.md b/solution/README_EN.md index bfc691f0e8f1b..38d6bfbc0a09c 100644 --- a/solution/README_EN.md +++ b/solution/README_EN.md @@ -2863,6 +2863,10 @@ Press Control+F(or Command+F on the | 2852 | [Sum of Remoteness of All Cells](/solution/2800-2899/2852.Sum%20of%20Remoteness%20of%20All%20Cells/README_EN.md) | | Medium | 🔒 | | 2853 | [Highest Salaries Difference](/solution/2800-2899/2853.Highest%20Salaries%20Difference/README_EN.md) | | Easy | 🔒 | | 2854 | [Rolling Average Steps](/solution/2800-2899/2854.Rolling%20Average%20Steps/README_EN.md) | | Medium | 🔒 | +| 2855 | [Minimum Right Shifts to Sort the Array](/solution/2800-2899/2855.Minimum%20Right%20Shifts%20to%20Sort%20the%20Array/README_EN.md) | | Easy | Biweekly Contest 113 | +| 2856 | [Minimum Array Length After Pair Removals](/solution/2800-2899/2856.Minimum%20Array%20Length%20After%20Pair%20Removals/README_EN.md) | | Medium | Biweekly Contest 113 | +| 2857 | [Count Pairs of Points With Distance k](/solution/2800-2899/2857.Count%20Pairs%20of%20Points%20With%20Distance%20k/README_EN.md) | | Medium | Biweekly Contest 113 | +| 2858 | [Minimum Edge Reversals So Every Node Is Reachable](/solution/2800-2899/2858.Minimum%20Edge%20Reversals%20So%20Every%20Node%20Is%20Reachable/README_EN.md) | | Hard | Biweekly Contest 113 | ## Copyright diff --git a/solution/summary.md b/solution/summary.md index 18d838387b24b..7bdedad7ca7b6 100644 --- a/solution/summary.md +++ b/solution/summary.md @@ -2910,3 +2910,7 @@ - [2852.Sum of Remoteness of All Cells](/solution/2800-2899/2852.Sum%20of%20Remoteness%20of%20All%20Cells/README.md) - [2853.Highest Salaries Difference](/solution/2800-2899/2853.Highest%20Salaries%20Difference/README.md) - [2854.Rolling Average Steps](/solution/2800-2899/2854.Rolling%20Average%20Steps/README.md) + - [2855.使数组成为递增数组的最少右移次数](/solution/2800-2899/2855.Minimum%20Right%20Shifts%20to%20Sort%20the%20Array/README.md) + - [2856.删除数对后的最小数组长度](/solution/2800-2899/2856.Minimum%20Array%20Length%20After%20Pair%20Removals/README.md) + - [2857.统计距离为 k 的点对](/solution/2800-2899/2857.Count%20Pairs%20of%20Points%20With%20Distance%20k/README.md) + - [2858.可以到达每一个节点的最少边反转次数](/solution/2800-2899/2858.Minimum%20Edge%20Reversals%20So%20Every%20Node%20Is%20Reachable/README.md) diff --git a/solution/summary_en.md b/solution/summary_en.md index ada48850ef5e3..b854fc88ccc12 100644 --- a/solution/summary_en.md +++ b/solution/summary_en.md @@ -2910,3 +2910,7 @@ - [2852.Sum of Remoteness of All Cells](/solution/2800-2899/2852.Sum%20of%20Remoteness%20of%20All%20Cells/README_EN.md) - [2853.Highest Salaries Difference](/solution/2800-2899/2853.Highest%20Salaries%20Difference/README_EN.md) - [2854.Rolling Average Steps](/solution/2800-2899/2854.Rolling%20Average%20Steps/README_EN.md) + - [2855.Minimum Right Shifts to Sort the Array](/solution/2800-2899/2855.Minimum%20Right%20Shifts%20to%20Sort%20the%20Array/README_EN.md) + - [2856.Minimum Array Length After Pair Removals](/solution/2800-2899/2856.Minimum%20Array%20Length%20After%20Pair%20Removals/README_EN.md) + - [2857.Count Pairs of Points With Distance k](/solution/2800-2899/2857.Count%20Pairs%20of%20Points%20With%20Distance%20k/README_EN.md) + - [2858.Minimum Edge Reversals So Every Node Is Reachable](/solution/2800-2899/2858.Minimum%20Edge%20Reversals%20So%20Every%20Node%20Is%20Reachable/README_EN.md)

AltStyle によって変換されたページ (->オリジナル) /