# Question

Formatted question description: https://leetcode.ca/all/1160.html

 1160. Find Words That Can Be Formed by Characters

You are given an array of strings words and a string chars.

A string is good if it can be formed by characters from chars (each character can only be used once).

Return the sum of lengths of all good strings in words.

Example 1:

Input: words = ["cat","bt","hat","tree"], chars = "atach"
Output: 6
Explanation:
The strings that can be formed are "cat" and "hat" so the answer is 3 + 3 = 6.

Example 2:

Input: words = ["hello","world","leetcode"], chars = "welldonehoneyr"
Output: 10
Explanation:
The strings that can be formed are "hello" and "world" so the answer is 5 + 5 = 10.

Note:

1 <= words.length <= 1000
1 <= words[i].length, chars.length <= 100
All strings contain lowercase English letters only.



# Algorithm

We need to check whether the frequency of each character of each word meets the available frequency that the character can provide. In other words, if the character frequency of the current word is higher (for example, “hello” requires two “l”s and there is only one “l” in “helo”, then we need to skip the word). Calculate and sum the length of a word. If the cycle of each character of a word is completed, the length of the word.

# Code

• 
public class Find_Words_That_Can_Be_Formed_by_Characters {

public static void main(String[] args) {
String[] words = {"cat","bt","hat","tree"};
String chars = "atach";
Find_Words_That_Can_Be_Formed_by_Characters find_words_that_can_be_formed_by_characters_1160 = new Find_Words_That_Can_Be_Formed_by_Characters();
System.out.println(find_words_that_can_be_formed_by_characters_1160.new Solution().countCharacters(words, chars));
}

class Solution {
public int countCharacters(String[] words, String chars) {
if (chars.equals("") || words == null || words.length ==0){
return 0;
}
HashMap<Character, Integer> map = new HashMap<>();

for (int i = 0; i < chars.length(); i++) {
if (map.get(chars.charAt(i)) == null){
map.put(chars.charAt(i), 1);
} else {
map.put(chars.charAt(i), map.get(chars.charAt(i))+1);
}
}

int ans = 0;
HashMap<Character, Integer> temp = new HashMap<>(map);
for (String word : words) {
for (int i = 0; i < word.length(); i++) {
if (map.containsKey(word.charAt(i))){
map.put(word.charAt(i),map.get(word.charAt(i))-1);
}
if (map.get(word.charAt(i)) == null || map.get(word.charAt(i)) < 0){
break;
}
if (i == word.length()-1){
ans += word.length();
}
}
map = new HashMap<>(temp);
}

return ans;
}
}

}

############

class Solution {
public int countCharacters(String[] words, String chars) {
int[] cnt = new int[26];
for (int i = 0; i < chars.length(); ++i) {
++cnt[chars.charAt(i) - 'a'];
}
int ans = 0;
for (String w : words) {
int[] wc = new int[26];
boolean ok = true;
for (int i = 0; i < w.length(); ++i) {
int j = w.charAt(i) - 'a';
if (++wc[j] > cnt[j]) {
ok = false;
break;
}
}
if (ok) {
ans += w.length();
}
}
return ans;
}
}

• class Solution:
def countCharacters(self, words: List[str], chars: str) -> int:
counter = Counter(chars)
ans = 0
for word in words:
cnt = Counter(word)
if all([counter[c] >= v for c, v in cnt.items()]):
ans += len(word)
return ans

############

# 1160. Find Words That Can Be Formed by Characters
# https://leetcode.com/problems/find-words-that-can-be-formed-by-characters/

class Solution:
def countCharacters(self, words: List[str], chars: str) -> int:
res = 0
n = len(words)
c2 = Counter(chars)

for i in range(n):
c1 = Counter(words[i])
if all((c2[c] - c1[c] >= 0) for c in c1):
res += len(words[i])

return res


• class Solution {
public:
int countCharacters(vector<string>& words, string chars) {
int cnt[26]{};
for (char& c : chars) {
++cnt[c - 'a'];
}
int ans = 0;
for (auto& w : words) {
int wc[26]{};
bool ok = true;
for (auto& c : w) {
int i = c - 'a';
if (++wc[i] > cnt[i]) {
ok = false;
break;
}
}
if (ok) {
ans += w.size();
}
}
return ans;
}
};

• func countCharacters(words []string, chars string) (ans int) {
cnt := [26]int{}
for _, c := range chars {
cnt[c-'a']++
}
for _, w := range words {
wc := [26]int{}
ok := true
for _, c := range w {
c -= 'a'
wc[c]++
if wc[c] > cnt[c] {
ok = false
break
}
}
if ok {
ans += len(w)
}
}
return
}

• function countCharacters(words: string[], chars: string): number {
const idx = (c: string) => c.charCodeAt(0) - 'a'.charCodeAt(0);
const cnt = new Array(26).fill(0);
for (const c of chars) {
cnt[idx(c)]++;
}
let ans = 0;
for (const w of words) {
const wc = new Array(26).fill(0);
let ok = true;
for (const c of w) {
if (++wc[idx(c)] > cnt[idx(c)]) {
ok = false;
break;
}
}
if (ok) {
ans += w.length;
}
}
return ans;
}


• class Solution {
/**
* @param String[] $words * @param String$chars
* @return Integer
*/
function countCharacters($words,$chars) {
$sum = 0; for ($i = 0; $i < strlen($chars); $i++) {$hashtable[$chars[$i]] += 1;
}
for ($j = 0;$j < count($words);$j++) {
$tmp =$hashtable;
$sum += strlen($words[$j]); for ($k = 0; $k < strlen($words[$j]);$k++) {
if (!isset($tmp[$words[$j][$k]]) || $tmp[$words[$j][$k]] === 0) {
$sum -= strlen($words[$j]); break; }$tmp[$words[$j][$k]] -= 1; } } return$sum;
}
}

• class Solution {
public int countCharacters(String[] words, String chars) {
int sum = 0;
for (String word : words) {
if (canFormWord(word, chars))
sum += word.length();
}
return sum;
}

public boolean canFormWord(String word, String chars) {
int[] wordCount = new int[26];
int[] charsCount = new int[26];
char[] wordArray = word.toCharArray();
for (char c : wordArray)
wordCount[c - 'a']++;
char[] charsArray = chars.toCharArray();
for (char c : charsArray)
charsCount[c - 'a']++;
for (int i = 0; i < 26; i++) {
if (wordCount[i] > charsCount[i])
return false;
}
return true;
}
}

############

class Solution {
public int countCharacters(String[] words, String chars) {
int[] cnt = new int[26];
for (int i = 0; i < chars.length(); ++i) {
++cnt[chars.charAt(i) - 'a'];
}
int ans = 0;
for (String w : words) {
int[] wc = new int[26];
boolean ok = true;
for (int i = 0; i < w.length(); ++i) {
int j = w.charAt(i) - 'a';
if (++wc[j] > cnt[j]) {
ok = false;
break;
}
}
if (ok) {
ans += w.length();
}
}
return ans;
}
}

• class Solution:
def countCharacters(self, words: List[str], chars: str) -> int:
counter = Counter(chars)
ans = 0
for word in words:
cnt = Counter(word)
if all([counter[c] >= v for c, v in cnt.items()]):
ans += len(word)
return ans

############

# 1160. Find Words That Can Be Formed by Characters
# https://leetcode.com/problems/find-words-that-can-be-formed-by-characters/

class Solution:
def countCharacters(self, words: List[str], chars: str) -> int:
res = 0
n = len(words)
c2 = Counter(chars)

for i in range(n):
c1 = Counter(words[i])
if all((c2[c] - c1[c] >= 0) for c in c1):
res += len(words[i])

return res


• class Solution {
public:
int countCharacters(vector<string>& words, string chars) {
int cnt[26]{};
for (char& c : chars) {
++cnt[c - 'a'];
}
int ans = 0;
for (auto& w : words) {
int wc[26]{};
bool ok = true;
for (auto& c : w) {
int i = c - 'a';
if (++wc[i] > cnt[i]) {
ok = false;
break;
}
}
if (ok) {
ans += w.size();
}
}
return ans;
}
};

• func countCharacters(words []string, chars string) (ans int) {
cnt := [26]int{}
for _, c := range chars {
cnt[c-'a']++
}
for _, w := range words {
wc := [26]int{}
ok := true
for _, c := range w {
c -= 'a'
wc[c]++
if wc[c] > cnt[c] {
ok = false
break
}
}
if ok {
ans += len(w)
}
}
return
}

• function countCharacters(words: string[], chars: string): number {
const idx = (c: string) => c.charCodeAt(0) - 'a'.charCodeAt(0);
const cnt = new Array(26).fill(0);
for (const c of chars) {
cnt[idx(c)]++;
}
let ans = 0;
for (const w of words) {
const wc = new Array(26).fill(0);
let ok = true;
for (const c of w) {
if (++wc[idx(c)] > cnt[idx(c)]) {
ok = false;
break;
}
}
if (ok) {
ans += w.length;
}
}
return ans;
}


• class Solution {
/**
* @param String[] $words * @param String$chars
* @return Integer
*/
function countCharacters($words,$chars) {
$sum = 0; for ($i = 0; $i < strlen($chars); $i++) {$hashtable[$chars[$i]] += 1;
}
for ($j = 0;$j < count($words);$j++) {
$tmp =$hashtable;
$sum += strlen($words[$j]); for ($k = 0; $k < strlen($words[$j]);$k++) {
if (!isset($tmp[$words[$j][$k]]) || $tmp[$words[$j][$k]] === 0) {
$sum -= strlen($words[$j]); break; }$tmp[$words[$j][$k]] -= 1; } } return$sum;
}
}