diff --git a/solution/3500-3599/3587.Minimum Adjacent Swaps to Alternate Parity/README.md b/solution/3500-3599/3587.Minimum Adjacent Swaps to Alternate Parity/README.md index 90c9434068509..e876d876331fa 100644 --- a/solution/3500-3599/3587.Minimum Adjacent Swaps to Alternate Parity/README.md +++ b/solution/3500-3599/3587.Minimum Adjacent Swaps to Alternate Parity/README.md @@ -94,32 +94,169 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3500-3599/3587.Mi -### 方法一 +### 方法一:分类讨论 + 贪心 + +对于一个有效排列,奇数和偶数的个数只能相差 1 或者相等。因此,如果奇数和偶数的个数相差超过 1,则无法构成有效排列,直接返回 -1。 + +我们用一个数组 $\text{pos}$ 来存储奇数和偶数的下标,其中 $\text{pos}[0]$ 存储偶数的下标,而 $\text{pos}[1]$ 存储奇数的下标。 + +如果奇数和偶数的个数相等,则可以有两种有效排列:奇数在偶数前面,或者偶数在奇数前面。我们可以计算这两种排列的交换次数,取最小值。 + +如果奇数的个数大于偶数的个数,则只有一种有效排列,即奇数在偶数前面。此时,我们只需要计算这种排列的交换次数。 + +因此,我们定义一个函数 $\text{calc}(k)$,其中 $k$ 表示第一个元素的奇偶性(0 表示偶数,1 表示奇数)。该函数计算从当前排列到以 $k$ 开头的有效排列所需的交换次数。我们只需要遍历 $\text{pos}[k]$ 中的下标,计算每个下标与其在有效排列中的位置之间的差值之和。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $\text{nums}$ 的长度。 #### Python3 ```python - +class Solution: + def minSwaps(self, nums: List[int]) -> int: + def calc(k: int) -> int: + return sum(abs(i - j) for i, j in zip(range(0, len(nums), 2), pos[k])) + + pos = [[], []] + for i, x in enumerate(nums): + pos[x & 1].append(i) + if abs(len(pos[0]) - len(pos[1])) > 1: + return -1 + if len(pos[0]) > len(pos[1]): + return calc(0) + if len(pos[0]) < len(pos[1]): + return calc(1) + return min(calc(0), calc(1)) ``` #### Java ```java - +class Solution { + private List[] pos = new List[2]; + private int[] nums; + + public int minSwaps(int[] nums) { + this.nums = nums; + Arrays.setAll(pos, k -> new ArrayList<>()); + for (int i = 0; i < nums.length; ++i) { + pos[nums[i] & 1].add(i); + } + if (Math.abs(pos[0].size() - pos[1].size()) > 1) { + return -1; + } + if (pos[0].size() > pos[1].size()) { + return calc(0); + } + if (pos[0].size() < pos[1].size()) { + return calc(1); + } + return Math.min(calc(0), calc(1)); + } + + private int calc(int k) { + int res = 0; + for (int i = 0; i < nums.length; i += 2) { + res += Math.abs(pos[k].get(i / 2) - i); + } + return res; + } +} ``` #### C++ ```cpp - +class Solution { +public: + int minSwaps(vector& nums) { + vector pos[2]; + for (int i = 0; i < nums.size(); ++i) { + pos[nums[i] & 1].push_back(i); + } + if (abs(int(pos[0].size() - pos[1].size())) > 1) { + return -1; + } + auto calc = [&](int k) { + int res = 0; + for (int i = 0; i < nums.size(); i += 2) { + res += abs(pos[k][i / 2] - i); + } + return res; + }; + if (pos[0].size() > pos[1].size()) { + return calc(0); + } + if (pos[0].size() < pos[1].size()) { + return calc(1); + } + return min(calc(0), calc(1)); + } +}; ``` #### Go ```go +func minSwaps(nums []int) int { + pos := [2][]int{} + for i, x := range nums { + pos[x&1] = append(pos[x&1], i) + } + if abs(len(pos[0])-len(pos[1])) > 1 { + return -1 + } + calc := func(k int) int { + res := 0 + for i := 0; i < len(nums); i += 2 { + res += abs(pos[k][i/2] - i) + } + return res + } + if len(pos[0]) > len(pos[1]) { + return calc(0) + } + if len(pos[0]) < len(pos[1]) { + return calc(1) + } + return min(calc(0), calc(1)) +} + +func abs(x int) int { + if x < 0 { + return -x + } + return x +} +``` +#### TypeScript + +```ts +function minSwaps(nums: number[]): number { + const pos: number[][] = [[], []]; + for (let i = 0; i < nums.length; ++i) { + pos[nums[i] & 1].push(i); + } + if (Math.abs(pos[0].length - pos[1].length) > 1) { + return -1; + } + const calc = (k: number): number => { + let res = 0; + for (let i = 0; i < nums.length; i += 2) { + res += Math.abs(pos[k][i >> 1] - i); + } + return res; + }; + if (pos[0].length > pos[1].length) { + return calc(0); + } + if (pos[0].length < pos[1].length) { + return calc(1); + } + return Math.min(calc(0), calc(1)); +} ``` diff --git a/solution/3500-3599/3587.Minimum Adjacent Swaps to Alternate Parity/README_EN.md b/solution/3500-3599/3587.Minimum Adjacent Swaps to Alternate Parity/README_EN.md index c1ca814aeee1b..257ab11211ab2 100644 --- a/solution/3500-3599/3587.Minimum Adjacent Swaps to Alternate Parity/README_EN.md +++ b/solution/3500-3599/3587.Minimum Adjacent Swaps to Alternate Parity/README_EN.md @@ -92,32 +92,169 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3500-3599/3587.Mi -### Solution 1 +### Solution 1: Case Analysis + Greedy + +For a valid arrangement, the number of odd and even numbers can only differ by 1 or be equal. Therefore, if the difference between the number of odd and even numbers is greater than 1, it is impossible to form a valid arrangement, and we should return -1 directly. + +We use an array $\text{pos}$ to store the indices of odd and even numbers, where $\text{pos}[0]$ stores the indices of even numbers and $\text{pos}[1]$ stores the indices of odd numbers. + +If the number of odd and even numbers is equal, there are two valid arrangements: odd numbers before even numbers, or even numbers before odd numbers. We can calculate the number of swaps required for both arrangements and take the minimum. + +If the number of odd numbers is greater than the number of even numbers, there is only one valid arrangement, which is odd numbers before even numbers. In this case, we only need to calculate the number of swaps for this arrangement. + +Therefore, we define a function $\text{calc}(k)$, where $k$ indicates the parity of the first element (0 for even, 1 for odd). This function calculates the number of swaps needed to transform the current arrangement into a valid arrangement starting with $k$. We just need to iterate over the indices in $\text{pos}[k]$ and sum the differences between each index and its position in the valid arrangement. + +The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of the array $\text{nums}$. #### Python3 ```python - +class Solution: + def minSwaps(self, nums: List[int]) -> int: + def calc(k: int) -> int: + return sum(abs(i - j) for i, j in zip(range(0, len(nums), 2), pos[k])) + + pos = [[], []] + for i, x in enumerate(nums): + pos[x & 1].append(i) + if abs(len(pos[0]) - len(pos[1])) > 1: + return -1 + if len(pos[0]) > len(pos[1]): + return calc(0) + if len(pos[0]) < len(pos[1]): + return calc(1) + return min(calc(0), calc(1)) ``` #### Java ```java - +class Solution { + private List[] pos = new List[2]; + private int[] nums; + + public int minSwaps(int[] nums) { + this.nums = nums; + Arrays.setAll(pos, k -> new ArrayList<>()); + for (int i = 0; i < nums.length; ++i) { + pos[nums[i] & 1].add(i); + } + if (Math.abs(pos[0].size() - pos[1].size()) > 1) { + return -1; + } + if (pos[0].size() > pos[1].size()) { + return calc(0); + } + if (pos[0].size() < pos[1].size()) { + return calc(1); + } + return Math.min(calc(0), calc(1)); + } + + private int calc(int k) { + int res = 0; + for (int i = 0; i < nums.length; i += 2) { + res += Math.abs(pos[k].get(i / 2) - i); + } + return res; + } +} ``` #### C++ ```cpp - +class Solution { +public: + int minSwaps(vector& nums) { + vector pos[2]; + for (int i = 0; i < nums.size(); ++i) { + pos[nums[i] & 1].push_back(i); + } + if (abs(int(pos[0].size() - pos[1].size())) > 1) { + return -1; + } + auto calc = [&](int k) { + int res = 0; + for (int i = 0; i < nums.size(); i += 2) { + res += abs(pos[k][i / 2] - i); + } + return res; + }; + if (pos[0].size() > pos[1].size()) { + return calc(0); + } + if (pos[0].size() < pos[1].size()) { + return calc(1); + } + return min(calc(0), calc(1)); + } +}; ``` #### Go ```go +func minSwaps(nums []int) int { + pos := [2][]int{} + for i, x := range nums { + pos[x&1] = append(pos[x&1], i) + } + if abs(len(pos[0])-len(pos[1])) > 1 { + return -1 + } + calc := func(k int) int { + res := 0 + for i := 0; i < len(nums); i += 2 { + res += abs(pos[k][i/2] - i) + } + return res + } + if len(pos[0]) > len(pos[1]) { + return calc(0) + } + if len(pos[0]) < len(pos[1]) { + return calc(1) + } + return min(calc(0), calc(1)) +} + +func abs(x int) int { + if x < 0 { + return -x + } + return x +} +``` +#### TypeScript + +```ts +function minSwaps(nums: number[]): number { + const pos: number[][] = [[], []]; + for (let i = 0; i < nums.length; ++i) { + pos[nums[i] & 1].push(i); + } + if (Math.abs(pos[0].length - pos[1].length) > 1) { + return -1; + } + const calc = (k: number): number => { + let res = 0; + for (let i = 0; i < nums.length; i += 2) { + res += Math.abs(pos[k][i >> 1] - i); + } + return res; + }; + if (pos[0].length > pos[1].length) { + return calc(0); + } + if (pos[0].length < pos[1].length) { + return calc(1); + } + return Math.min(calc(0), calc(1)); +} ``` diff --git a/solution/3500-3599/3587.Minimum Adjacent Swaps to Alternate Parity/Solution.cpp b/solution/3500-3599/3587.Minimum Adjacent Swaps to Alternate Parity/Solution.cpp new file mode 100644 index 0000000000000..68ee7e7e98ea8 --- /dev/null +++ b/solution/3500-3599/3587.Minimum Adjacent Swaps to Alternate Parity/Solution.cpp @@ -0,0 +1,26 @@ +class Solution { +public: + int minSwaps(vector& nums) { + vector pos[2]; + for (int i = 0; i < nums.size(); ++i) { + pos[nums[i] & 1].push_back(i); + } + if (abs(int(pos[0].size() - pos[1].size())) > 1) { + return -1; + } + auto calc = [&](int k) { + int res = 0; + for (int i = 0; i < nums.size(); i += 2) { + res += abs(pos[k][i / 2] - i); + } + return res; + }; + if (pos[0].size() > pos[1].size()) { + return calc(0); + } + if (pos[0].size() < pos[1].size()) { + return calc(1); + } + return min(calc(0), calc(1)); + } +}; diff --git a/solution/3500-3599/3587.Minimum Adjacent Swaps to Alternate Parity/Solution.go b/solution/3500-3599/3587.Minimum Adjacent Swaps to Alternate Parity/Solution.go new file mode 100644 index 0000000000000..fccba76dd4b87 --- /dev/null +++ b/solution/3500-3599/3587.Minimum Adjacent Swaps to Alternate Parity/Solution.go @@ -0,0 +1,30 @@ +func minSwaps(nums []int) int { + pos := [2][]int{} + for i, x := range nums { + pos[x&1] = append(pos[x&1], i) + } + if abs(len(pos[0])-len(pos[1])) > 1 { + return -1 + } + calc := func(k int) int { + res := 0 + for i := 0; i < len(nums); i += 2 { + res += abs(pos[k][i/2] - i) + } + return res + } + if len(pos[0]) > len(pos[1]) { + return calc(0) + } + if len(pos[0]) < len(pos[1]) { + return calc(1) + } + return min(calc(0), calc(1)) +} + +func abs(x int) int { + if x < 0 { + return -x + } + return x +} diff --git a/solution/3500-3599/3587.Minimum Adjacent Swaps to Alternate Parity/Solution.java b/solution/3500-3599/3587.Minimum Adjacent Swaps to Alternate Parity/Solution.java new file mode 100644 index 0000000000000..c48d479dee10c --- /dev/null +++ b/solution/3500-3599/3587.Minimum Adjacent Swaps to Alternate Parity/Solution.java @@ -0,0 +1,30 @@ +class Solution { + private List[] pos = new List[2]; + private int[] nums; + + public int minSwaps(int[] nums) { + this.nums = nums; + Arrays.setAll(pos, k -> new ArrayList<>()); + for (int i = 0; i < nums.length; ++i) { + pos[nums[i] & 1].add(i); + } + if (Math.abs(pos[0].size() - pos[1].size()) > 1) { + return -1; + } + if (pos[0].size() > pos[1].size()) { + return calc(0); + } + if (pos[0].size() < pos[1].size()) { + return calc(1); + } + return Math.min(calc(0), calc(1)); + } + + private int calc(int k) { + int res = 0; + for (int i = 0; i < nums.length; i += 2) { + res += Math.abs(pos[k].get(i / 2) - i); + } + return res; + } +} \ No newline at end of file diff --git a/solution/3500-3599/3587.Minimum Adjacent Swaps to Alternate Parity/Solution.py b/solution/3500-3599/3587.Minimum Adjacent Swaps to Alternate Parity/Solution.py new file mode 100644 index 0000000000000..b71b1d204f879 --- /dev/null +++ b/solution/3500-3599/3587.Minimum Adjacent Swaps to Alternate Parity/Solution.py @@ -0,0 +1,15 @@ +class Solution: + def minSwaps(self, nums: List[int]) -> int: + def calc(k: int) -> int: + return sum(abs(i - j) for i, j in zip(range(0, len(nums), 2), pos[k])) + + pos = [[], []] + for i, x in enumerate(nums): + pos[x & 1].append(i) + if abs(len(pos[0]) - len(pos[1])) > 1: + return -1 + if len(pos[0]) > len(pos[1]): + return calc(0) + if len(pos[0]) < len(pos[1]): + return calc(1) + return min(calc(0), calc(1)) diff --git a/solution/3500-3599/3587.Minimum Adjacent Swaps to Alternate Parity/Solution.ts b/solution/3500-3599/3587.Minimum Adjacent Swaps to Alternate Parity/Solution.ts new file mode 100644 index 0000000000000..8cad15adccf22 --- /dev/null +++ b/solution/3500-3599/3587.Minimum Adjacent Swaps to Alternate Parity/Solution.ts @@ -0,0 +1,23 @@ +function minSwaps(nums: number[]): number { + const pos: number[][] = [[], []]; + for (let i = 0; i < nums.length; ++i) { + pos[nums[i] & 1].push(i); + } + if (Math.abs(pos[0].length - pos[1].length) > 1) { + return -1; + } + const calc = (k: number): number => { + let res = 0; + for (let i = 0; i < nums.length; i += 2) { + res += Math.abs(pos[k][i >> 1] - i); + } + return res; + }; + if (pos[0].length > pos[1].length) { + return calc(0); + } + if (pos[0].length < pos[1].length) { + return calc(1); + } + return Math.min(calc(0), calc(1)); +}