Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add solutions to lc problem: No.1897 #3858

Merged
merged 1 commit into from
Dec 14, 2024
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 @@ -60,7 +60,13 @@ tags:

<!-- solution:start -->

### 方法一
### 方法一:计数

根据题目描述,只要每个字符的出现次数能被字符串数组的长度整除,就可以通过移动字符使所有字符串相等。

因此,我们用哈希表或者一个长度为 $26$ 的整数数组 $\textit{cnt}$ 统计每个字符出现的次数,最后判断是否每个字符的出现次数能被字符串数组的长度整除即可。

时间复杂度 $O(L)$,空间复杂度 $O(|\Sigma|)$。其中 $L$ 为数组 $\textit{words}$ 中所有字符串的长度之和,而 $\Sigma$ 为字符集,这里为小写字母集合,所以 $|\Sigma|=26$。

<!-- tabs:start -->

Expand All @@ -69,28 +75,28 @@ tags:
```python
class Solution:
def makeEqual(self, words: List[str]) -> bool:
counter = Counter()
for word in words:
for c in word:
counter[c] += 1
cnt = Counter()
for w in words:
for c in w:
cnt[c] += 1
n = len(words)
return all(count % n == 0 for count in counter.values())
return all(v % n == 0 for v in cnt.values())
```

#### Java

```java
class Solution {
public boolean makeEqual(String[] words) {
int[] counter = new int[26];
for (String word : words) {
for (char c : word.toCharArray()) {
++counter[c - 'a'];
int[] cnt = new int[26];
for (var w : words) {
for (char c : w.toCharArray()) {
++cnt[c - 'a'];
}
}
int n = words.length;
for (int i = 0; i < 26; ++i) {
if (counter[i] % n != 0) {
for (int v : cnt) {
if (v % n != 0) {
return false;
}
}
Expand All @@ -105,15 +111,17 @@ class Solution {
class Solution {
public:
bool makeEqual(vector<string>& words) {
vector<int> counter(26, 0);
for (string word : words) {
for (char c : word) {
++counter[c - 'a'];
int cnt[26]{};
for (const auto& w : words) {
for (const auto& c : w) {
++cnt[c - 'a'];
}
}
int n = words.size();
for (int count : counter) {
if (count % n != 0) return false;
for (int i = 0; i < 26; ++i) {
if (cnt[i] % n != 0) {
return false;
}
}
return true;
}
Expand All @@ -124,15 +132,15 @@ public:

```go
func makeEqual(words []string) bool {
counter := [26]int{}
for _, word := range words {
for _, c := range word {
counter[c-'a']++
cnt := [26]int{}
for _, w := range words {
for _, c := range w {
cnt[c-'a']++
}
}
n := len(words)
for _, count := range counter {
if count%n != 0 {
for _, v := range cnt {
if v%n != 0 {
return false
}
}
Expand All @@ -144,20 +152,33 @@ func makeEqual(words []string) bool {

```ts
function makeEqual(words: string[]): boolean {
let n = words.length;
let letters = new Array(26).fill(0);
for (let word of words) {
for (let i = 0; i < word.length; ++i) {
++letters[word.charCodeAt(i) - 97];
const cnt: Record<string, number> = {};
for (const w of words) {
for (const c of w) {
cnt[c] = (cnt[c] || 0) + 1;
}
}
const n = words.length;
return Object.values(cnt).every(v => v % n === 0);
}
```

#### Rust

for (let i = 0; i < letters.length; ++i) {
if (letters[i] % n != 0) {
return false;
```rust
impl Solution {
pub fn make_equal(words: Vec<String>) -> bool {
let mut cnt = std::collections::HashMap::new();

for word in words.iter() {
for c in word.chars() {
*cnt.entry(c).or_insert(0) += 1;
}
}

let n = words.len();
cnt.values().all(|&v| v % n == 0)
}
return true;
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,13 @@ All the strings are now equal to &quot;abc&quot;, so return <code>true</code>.

<!-- solution:start -->

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

According to the problem description, as long as the occurrence count of each character can be divided by the length of the string array, it is possible to redistribute the characters to make all strings equal.

Therefore, we use a hash table or an integer array of length $26$ $\textit{cnt}$ to count the occurrences of each character. Finally, we check if the occurrence count of each character can be divided by the length of the string array.

The time complexity is $O(L)$, and the space complexity is $O(|\Sigma|)$. Here, $L$ is the total length of all strings in the array $\textit{words}$, and $\Sigma$ is the character set, which is the set of lowercase letters, so $|\Sigma|=26$.

<!-- tabs:start -->

Expand All @@ -69,28 +75,28 @@ All the strings are now equal to &quot;abc&quot;, so return <code>true</code>.
```python
class Solution:
def makeEqual(self, words: List[str]) -> bool:
counter = Counter()
for word in words:
for c in word:
counter[c] += 1
cnt = Counter()
for w in words:
for c in w:
cnt[c] += 1
n = len(words)
return all(count % n == 0 for count in counter.values())
return all(v % n == 0 for v in cnt.values())
```

#### Java

```java
class Solution {
public boolean makeEqual(String[] words) {
int[] counter = new int[26];
for (String word : words) {
for (char c : word.toCharArray()) {
++counter[c - 'a'];
int[] cnt = new int[26];
for (var w : words) {
for (char c : w.toCharArray()) {
++cnt[c - 'a'];
}
}
int n = words.length;
for (int i = 0; i < 26; ++i) {
if (counter[i] % n != 0) {
for (int v : cnt) {
if (v % n != 0) {
return false;
}
}
Expand All @@ -105,15 +111,17 @@ class Solution {
class Solution {
public:
bool makeEqual(vector<string>& words) {
vector<int> counter(26, 0);
for (string word : words) {
for (char c : word) {
++counter[c - 'a'];
int cnt[26]{};
for (const auto& w : words) {
for (const auto& c : w) {
++cnt[c - 'a'];
}
}
int n = words.size();
for (int count : counter) {
if (count % n != 0) return false;
for (int i = 0; i < 26; ++i) {
if (cnt[i] % n != 0) {
return false;
}
}
return true;
}
Expand All @@ -124,15 +132,15 @@ public:

```go
func makeEqual(words []string) bool {
counter := [26]int{}
for _, word := range words {
for _, c := range word {
counter[c-'a']++
cnt := [26]int{}
for _, w := range words {
for _, c := range w {
cnt[c-'a']++
}
}
n := len(words)
for _, count := range counter {
if count%n != 0 {
for _, v := range cnt {
if v%n != 0 {
return false
}
}
Expand All @@ -144,20 +152,33 @@ func makeEqual(words []string) bool {

```ts
function makeEqual(words: string[]): boolean {
let n = words.length;
let letters = new Array(26).fill(0);
for (let word of words) {
for (let i = 0; i < word.length; ++i) {
++letters[word.charCodeAt(i) - 97];
const cnt: Record<string, number> = {};
for (const w of words) {
for (const c of w) {
cnt[c] = (cnt[c] || 0) + 1;
}
}
const n = words.length;
return Object.values(cnt).every(v => v % n === 0);
}
```

#### Rust

for (let i = 0; i < letters.length; ++i) {
if (letters[i] % n != 0) {
return false;
```rust
impl Solution {
pub fn make_equal(words: Vec<String>) -> bool {
let mut cnt = std::collections::HashMap::new();

for word in words.iter() {
for c in word.chars() {
*cnt.entry(c).or_insert(0) += 1;
}
}

let n = words.len();
cnt.values().all(|&v| v % n == 0)
}
return true;
}
```

Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
class Solution {
public:
bool makeEqual(vector<string>& words) {
vector<int> counter(26, 0);
for (string word : words) {
for (char c : word) {
++counter[c - 'a'];
int cnt[26]{};
for (const auto& w : words) {
for (const auto& c : w) {
++cnt[c - 'a'];
}
}
int n = words.size();
for (int count : counter) {
if (count % n != 0) return false;
for (int i = 0; i < 26; ++i) {
if (cnt[i] % n != 0) {
return false;
}
}
return true;
}
};
};
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
func makeEqual(words []string) bool {
counter := [26]int{}
for _, word := range words {
for _, c := range word {
counter[c-'a']++
cnt := [26]int{}
for _, w := range words {
for _, c := range w {
cnt[c-'a']++
}
}
n := len(words)
for _, count := range counter {
if count%n != 0 {
for _, v := range cnt {
if v%n != 0 {
return false
}
}
return true
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
class Solution {
public boolean makeEqual(String[] words) {
int[] counter = new int[26];
for (String word : words) {
for (char c : word.toCharArray()) {
++counter[c - 'a'];
int[] cnt = new int[26];
for (var w : words) {
for (char c : w.toCharArray()) {
++cnt[c - 'a'];
}
}
int n = words.length;
for (int i = 0; i < 26; ++i) {
if (counter[i] % n != 0) {
for (int v : cnt) {
if (v % n != 0) {
return false;
}
}
return true;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
class Solution:
def makeEqual(self, words: List[str]) -> bool:
counter = Counter()
for word in words:
for c in word:
counter[c] += 1
cnt = Counter()
for w in words:
for c in w:
cnt[c] += 1
n = len(words)
return all(count % n == 0 for count in counter.values())
return all(v % n == 0 for v in cnt.values())
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
impl Solution {
pub fn make_equal(words: Vec<String>) -> bool {
let mut cnt = std::collections::HashMap::new();

for word in words.iter() {
for c in word.chars() {
*cnt.entry(c).or_insert(0) += 1;
}
}

let n = words.len();
cnt.values().all(|&v| v % n == 0)
}
}
Loading
Loading