Skip to content

Instantly share code, notes, and snippets.

@t-eckert
Last active June 30, 2021 23:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save t-eckert/e9d86011fb4411a117396a1bc61e6cde to your computer and use it in GitHub Desktop.
Save t-eckert/e9d86011fb4411a117396a1bc61e6cde to your computer and use it in GitHub Desktop.
Go Solution to LeetCode 1897
package main
import (
"fmt"
"strings"
)
/* Redistribute Characters to Make All Strings Equal
LeetCode 1897: https://leetcode.com/contest/weekly-contest-245/problems/redistribute-characters-to-make-all-strings-equal/
You are given an array of strings words (0-indexed).
In one operation, pick two distinct indices i and j, where words[i] is a non-empty string, and move any character from
words[i] to any position in words[j].
Return true if you can make every string in words equal using any number of operations, and false otherwise.
Example 1:
Input: words = ["abc","aabc","bc"]
Output: true
Explanation: Move the first 'a' in words[1] to the front of words[2],
to make words[1] = "abc" and words[2] = "abc".
All the strings are now equal to "abc", so return true.
Example 2:
Input: words = ["ab","a"]
Output: false
Explanation: It is impossible to make all the strings equal using the operation.
Solution:
If the count of each unique character is divisible by the number of given words, a solution can be found and true
should be returned, otherwise return false.
Applying this to Example 1, for the unique characters "a", "b", and "c", each appears 3 times. The number of words is 3.
As 3 is evenly divisible by 3, a solution can be found.
In Example 2, there are 2 instances of "a" and 1 instance of "b", as 1 is not evenly divisible by 2, a solution cannot
be found.
*/
func main() {
charCollectionsDistrubutable := []string{"abc", "aabc", "bc"}
charCollectionsNotDistrubutable := []string{"abc", "abc", "bc"}
fmt.Println("true ->", AreCharsDistributable(charCollectionsDistrubutable))
fmt.Println("false ->", AreCharsDistributable(charCollectionsNotDistrubutable))
}
// Returns true if characters in the words can be distributed equally between the given number of words,
// false otherwise.
func AreCharsDistributable(words []string) bool {
tally := TallyChars(strings.Join(words, ""))
return AllDivisible(tally, len(words))
}
// Returns an array with the count of each unique character in the given string.
func TallyChars(str string) []int {
charCount := make(map[rune]int)
for _, char := range str {
if _, ok := charCount[char]; ok {
charCount[char]++
} else {
charCount[char] = 1
}
}
charTally := make([]int, 0, len(charCount))
for _, count := range charCount {
charTally = append(charTally, count)
}
return charTally
}
// Returns true if every dividend in the array is evenly divisible by the divisor, false otherwise.
func AllDivisible(dividends []int, divisor int) bool {
for _, dividend := range dividends {
if dividend%divisor != 0 {
return false
}
}
return true
}
@dcaponi
Copy link

dcaponi commented Jun 29, 2021

This looks like solid go code! 🎉

Nitpick:
On L59 you can use count++

Micro-optimization here:
on L65 don't you know the length of charTally? Is it not the same length as charCount? It would save a bunch of reallocation cycles to make([]int, len(charCount) and use for k, v := range charCount {...} (use k, v for ranging over a map) and allocate a counter variable i for placing the count in the charTally array.

@hunter32292
Copy link

You can generate slices in two ways:

	// Initialize it with a predefined length
	func convert(foos []Foo) []Bar {
		bars := make([]Bar, len(foos))
		for i, foo := range foos {
			bars[i] = fooToBar(foo)
		}
		return bars
	}

	// initialize it with a 0-length and predefined capacity
	func convert(foos []Foo) []Bar {
		bars := make([]Bar, 0, len(foos))
		for _, foo := range foos {
			bars = append(bars, fooToBar(foo))
		}
		return bars
	}

Initialize it with a predefined length is faster, but you may prefer two because it's just easier to deal with
Slices grow by Double after 25% utilization reached, so keep this in mind for performance.

Looks good though, keep it up!

@t-eckert
Copy link
Author

These are great! I made some updates!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment