Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ tags:

两个数 $a$ 和 $b$ 的和能被 $k$ 整除,当且仅当这两个数分别对 $k$ 取模的结果之和能被 $k$ 整除。

因此,我们可以统计数组中每个数对 $k$ 取模的结果,即余数,记录在数组 `cnt` 中。然后我们遍历数组 `cnt`,对于范围在 $[1,..k-1]$ 的每个数 $i$,如果 $cnt[i]$ 和 $cnt[k-i]$ 的值不相等,说明无法将数组中的数字分为 $n/2$ 对,使得每对数字的和都能被 $k$ 整除。如果 $cnt[0]$ 的值不是偶数,也说明无法将数组中的数字分为 $n/2$ 对,使得每对数字的和都能被 $k$ 整除。
因此,我们可以统计数组中每个数对 $k$ 取模的结果,即余数,记录在数组 $\textit{cnt}$ 中。然后我们遍历数组 $\textit{cnt}$,对于范围在 $[1,..k-1]$ 的每个数 $i$,如果 $\textit{cnt}[i]$ 和 $\textit{cnt}[k-i]$ 的值不相等,说明无法将数组中的数字分为 $n/2$ 对,使得每对数字的和都能被 $k$ 整除。如果 $\textit{cnt}[0]$ 的值不是偶数,也说明无法将数组中的数字分为 $n/2$ 对,使得每对数字的和都能被 $k$ 整除。

时间复杂度 $O(n)$,空间复杂度 $O(k)$。其中 $n$ 为数组 `arr` 的长度。
时间复杂度 $O(n)$,其中 $n$ 为数组 $\textit{arr}$ 的长度。空间复杂度 $O(k)$

<!-- tabs:start -->

Expand Down Expand Up @@ -149,36 +149,59 @@ func canArrange(arr []int, k int) bool {

```ts
function canArrange(arr: number[], k: number): boolean {
const cnt = Array(k).fill(0);

const cnt: number[] = Array(k).fill(0);
for (const x of arr) {
cnt[((x % k) + k) % k]++;
++cnt[((x % k) + k) % k];
}

for (let i = 1; i < k; i++) {
if (cnt[i] !== cnt[k - i]) return false;
for (let i = 1; i < k; ++i) {
if (cnt[i] !== cnt[k - i]) {
return false;
}
}

return cnt[0] % 2 === 0;
}
```

#### Rust

```rust
impl Solution {
pub fn can_arrange(arr: Vec<i32>, k: i32) -> bool {
let k = k as usize;
let mut cnt = vec![0; k];
for &x in &arr {
cnt[((x % k as i32 + k as i32) % k as i32) as usize] += 1;
}
for i in 1..k {
if cnt[i] != cnt[k - i] {
return false;
}
}
cnt[0] % 2 == 0
}
}
```

#### JavaScript

```js
function canArrange(arr, k) {
/**
* @param {number[]} arr
* @param {number} k
* @return {boolean}
*/
var canArrange = function (arr, k) {
const cnt = Array(k).fill(0);

for (const x of arr) {
cnt[((x % k) + k) % k]++;
++cnt[((x % k) + k) % k];
}

for (let i = 1; i < k; i++) {
if (cnt[i] !== cnt[k - i]) return false;
for (let i = 1; i < k; ++i) {
if (cnt[i] !== cnt[k - i]) {
return false;
}
}

return cnt[0] % 2 === 0;
}
};
```

<!-- tabs:end -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,13 @@ tags:

<!-- solution:start -->

### Solution 1
### Solution 1: Counting Remainders

The sum of two numbers $a$ and $b$ is divisible by $k$ if and only if the sum of their remainders when divided by $k$ is divisible by $k$.

Therefore, we can count the remainder of each number in the array when divided by $k$, and record them in an array $\textit{cnt}$. Then we traverse the array $\textit{cnt}$. For each number $i$ in the range $[1,..k-1]$, if the values of $\textit{cnt}[i]$ and $\textit{cnt}[k-i]$ are not equal, it means we cannot divide the numbers in the array into $n/2$ pairs such that the sum of each pair is divisible by $k$. Similarly, if the value of $\textit{cnt}[0]$ is not even, it also means we cannot divide the numbers in the array into $n/2$ pairs such that the sum of each pair is divisible by $k$.

The time complexity is $O(n)$, where $n$ is the length of the array $\textit{arr}$. The space complexity is $O(k)$.

<!-- tabs:start -->

Expand Down Expand Up @@ -141,36 +147,59 @@ func canArrange(arr []int, k int) bool {

```ts
function canArrange(arr: number[], k: number): boolean {
const cnt = Array(k).fill(0);

const cnt: number[] = Array(k).fill(0);
for (const x of arr) {
cnt[((x % k) + k) % k]++;
++cnt[((x % k) + k) % k];
}

for (let i = 1; i < k; i++) {
if (cnt[i] !== cnt[k - i]) return false;
for (let i = 1; i < k; ++i) {
if (cnt[i] !== cnt[k - i]) {
return false;
}
}

return cnt[0] % 2 === 0;
}
```

#### Rust

```rust
impl Solution {
pub fn can_arrange(arr: Vec<i32>, k: i32) -> bool {
let k = k as usize;
let mut cnt = vec![0; k];
for &x in &arr {
cnt[((x % k as i32 + k as i32) % k as i32) as usize] += 1;
}
for i in 1..k {
if cnt[i] != cnt[k - i] {
return false;
}
}
cnt[0] % 2 == 0
}
}
```

#### JavaScript

```js
function canArrange(arr, k) {
/**
* @param {number[]} arr
* @param {number} k
* @return {boolean}
*/
var canArrange = function (arr, k) {
const cnt = Array(k).fill(0);

for (const x of arr) {
cnt[((x % k) + k) % k]++;
++cnt[((x % k) + k) % k];
}

for (let i = 1; i < k; i++) {
if (cnt[i] !== cnt[k - i]) return false;
for (let i = 1; i < k; ++i) {
if (cnt[i] !== cnt[k - i]) {
return false;
}
}

return cnt[0] % 2 === 0;
}
};
```

<!-- tabs:end -->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
function canArrange(arr, k) {
/**
* @param {number[]} arr
* @param {number} k
* @return {boolean}
*/
var canArrange = function (arr, k) {
const cnt = Array(k).fill(0);

for (const x of arr) {
cnt[((x % k) + k) % k]++;
++cnt[((x % k) + k) % k];
}

for (let i = 1; i < k; i++) {
if (cnt[i] !== cnt[k - i]) return false;
for (let i = 1; i < k; ++i) {
if (cnt[i] !== cnt[k - i]) {
return false;
}
}

return cnt[0] % 2 === 0;
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
impl Solution {
pub fn can_arrange(arr: Vec<i32>, k: i32) -> bool {
let k = k as usize;
let mut cnt = vec![0; k];
for &x in &arr {
cnt[((x % k as i32 + k as i32) % k as i32) as usize] += 1;
}
for i in 1..k {
if cnt[i] != cnt[k - i] {
return false;
}
}
cnt[0] % 2 == 0
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
function canArrange(arr: number[], k: number): boolean {
const cnt = Array(k).fill(0);

const cnt: number[] = Array(k).fill(0);
for (const x of arr) {
cnt[((x % k) + k) % k]++;
++cnt[((x % k) + k) % k];
}

for (let i = 1; i < k; i++) {
if (cnt[i] !== cnt[k - i]) return false;
for (let i = 1; i < k; ++i) {
if (cnt[i] !== cnt[k - i]) {
return false;
}
}

return cnt[0] % 2 === 0;
}