Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Break down a hard problem into reliable checkpoints, edge-case handling, and complexity trade-offs.
You are given an array of strings ideas that represents a list of names to be used in the process of naming a company. The process of naming a company is as follows:
ideas, call them ideaA and ideaB.ideaA and ideaB with each other.ideas, then the name ideaA ideaB (the concatenation of ideaA and ideaB, separated by a space) is a valid company name.Return the number of distinct valid names for the company.
Example 1:
Input: ideas = ["coffee","donuts","time","toffee"]
Output: 6
Explanation: The following selections are valid:
- ("coffee", "donuts"): The company name created is "doffee conuts".
- ("donuts", "coffee"): The company name created is "conuts doffee".
- ("donuts", "time"): The company name created is "tonuts dime".
- ("donuts", "toffee"): The company name created is "tonuts doffee".
- ("time", "donuts"): The company name created is "dime tonuts".
- ("toffee", "donuts"): The company name created is "doffee tonuts".
Therefore, there are a total of 6 distinct company names.
The following are some examples of invalid selections:
- ("coffee", "time"): The name "toffee" formed after swapping already exists in the original array.
- ("time", "toffee"): Both names are still the same after swapping and exist in the original array.
- ("coffee", "toffee"): Both names formed after swapping already exist in the original array.
Example 2:
Input: ideas = ["lack","back"] Output: 0 Explanation: There are no valid selections. Therefore, 0 is returned.
Constraints:
2 <= ideas.length <= 5 * 1041 <= ideas[i].length <= 10ideas[i] consists of lowercase English letters.ideas are unique.Problem summary: You are given an array of strings ideas that represents a list of names to be used in the process of naming a company. The process of naming a company is as follows: Choose 2 distinct names from ideas, call them ideaA and ideaB. Swap the first letters of ideaA and ideaB with each other. If both of the new names are not found in the original ideas, then the name ideaA ideaB (the concatenation of ideaA and ideaB, separated by a space) is a valid company name. Otherwise, it is not a valid name. Return the number of distinct valid names for the company.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Hash Map · Bit Manipulation
["coffee","donuts","time","toffee"]
["lack","back"]
Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #2306: Naming a Company
class Solution {
public long distinctNames(String[] ideas) {
Set<String> s = new HashSet<>();
for (String v : ideas) {
s.add(v);
}
int[][] f = new int[26][26];
for (String v : ideas) {
char[] t = v.toCharArray();
int i = t[0] - 'a';
for (int j = 0; j < 26; ++j) {
t[0] = (char) (j + 'a');
if (!s.contains(String.valueOf(t))) {
++f[i][j];
}
}
}
long ans = 0;
for (String v : ideas) {
char[] t = v.toCharArray();
int i = t[0] - 'a';
for (int j = 0; j < 26; ++j) {
t[0] = (char) (j + 'a');
if (!s.contains(String.valueOf(t))) {
ans += f[j][i];
}
}
}
return ans;
}
}
// Accepted solution for LeetCode #2306: Naming a Company
func distinctNames(ideas []string) (ans int64) {
s := map[string]bool{}
for _, v := range ideas {
s[v] = true
}
f := [26][26]int{}
for _, v := range ideas {
i := int(v[0] - 'a')
t := []byte(v)
for j := 0; j < 26; j++ {
t[0] = 'a' + byte(j)
if !s[string(t)] {
f[i][j]++
}
}
}
for _, v := range ideas {
i := int(v[0] - 'a')
t := []byte(v)
for j := 0; j < 26; j++ {
t[0] = 'a' + byte(j)
if !s[string(t)] {
ans += int64(f[j][i])
}
}
}
return
}
# Accepted solution for LeetCode #2306: Naming a Company
class Solution:
def distinctNames(self, ideas: List[str]) -> int:
s = set(ideas)
f = [[0] * 26 for _ in range(26)]
for v in ideas:
i = ord(v[0]) - ord('a')
t = list(v)
for j in range(26):
t[0] = chr(ord('a') + j)
if ''.join(t) not in s:
f[i][j] += 1
ans = 0
for v in ideas:
i = ord(v[0]) - ord('a')
t = list(v)
for j in range(26):
t[0] = chr(ord('a') + j)
if ''.join(t) not in s:
ans += f[j][i]
return ans
// Accepted solution for LeetCode #2306: Naming a Company
/**
* [2306] Naming a Company
*
* You are given an array of strings ideas that represents a list of names to be used in the process of naming a company. The process of naming a company is as follows:
* <ol>
* Choose 2 distinct names from ideas, call them ideaA and ideaB.
* Swap the first letters of ideaA and ideaB with each other.
* If both of the new names are not found in the original ideas, then the name ideaA ideaB (the concatenation of ideaA and ideaB, separated by a space) is a valid company name.
* Otherwise, it is not a valid name.
* </ol>
* Return the number of distinct valid names for the company.
*
* Example 1:
*
* Input: ideas = ["coffee","donuts","time","toffee"]
* Output: 6
* Explanation: The following selections are valid:
* - ("coffee", "donuts"): The company name created is "doffee conuts".
* - ("donuts", "coffee"): The company name created is "conuts doffee".
* - ("donuts", "time"): The company name created is "tonuts dime".
* - ("donuts", "toffee"): The company name created is "tonuts doffee".
* - ("time", "donuts"): The company name created is "dime tonuts".
* - ("toffee", "donuts"): The company name created is "doffee tonuts".
* Therefore, there are a total of 6 distinct company names.
* The following are some examples of invalid selections:
* - ("coffee", "time"): The name "toffee" formed after swapping already exists in the original array.
* - ("time", "toffee"): Both names are still the same after swapping and exist in the original array.
* - ("coffee", "toffee"): Both names formed after swapping already exist in the original array.
*
* Example 2:
*
* Input: ideas = ["lack","back"]
* Output: 0
* Explanation: There are no valid selections. Therefore, 0 is returned.
*
*
* Constraints:
*
* 2 <= ideas.length <= 5 * 10^4
* 1 <= ideas[i].length <= 10
* ideas[i] consists of lowercase English letters.
* All the strings in ideas are unique.
*
*/
pub struct Solution {}
// problem: https://leetcode.com/problems/naming-a-company/
// discuss: https://leetcode.com/problems/naming-a-company/discuss/?currentPage=1&orderBy=most_votes&query=
// submission codes start here
impl Solution {
pub fn distinct_names(ideas: Vec<String>) -> i64 {
0
}
}
// submission codes end
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[ignore]
fn test_2306_example_1() {
let ideas = vec_string!["coffee", "donuts", "time", "toffee"];
let result = 6;
assert_eq!(Solution::distinct_names(ideas), result);
}
#[test]
#[ignore]
fn test_2306_example_2() {
let ideas = vec_string!["lack", "back"];
let result = 0;
assert_eq!(Solution::distinct_names(ideas), result);
}
}
// Accepted solution for LeetCode #2306: Naming a Company
// Auto-generated TypeScript example from java.
function exampleSolution(): void {
}
// Reference (java):
// // Accepted solution for LeetCode #2306: Naming a Company
// class Solution {
// public long distinctNames(String[] ideas) {
// Set<String> s = new HashSet<>();
// for (String v : ideas) {
// s.add(v);
// }
// int[][] f = new int[26][26];
// for (String v : ideas) {
// char[] t = v.toCharArray();
// int i = t[0] - 'a';
// for (int j = 0; j < 26; ++j) {
// t[0] = (char) (j + 'a');
// if (!s.contains(String.valueOf(t))) {
// ++f[i][j];
// }
// }
// }
// long ans = 0;
// for (String v : ideas) {
// char[] t = v.toCharArray();
// int i = t[0] - 'a';
// for (int j = 0; j < 26; ++j) {
// t[0] = (char) (j + 'a');
// if (!s.contains(String.valueOf(t))) {
// ans += f[j][i];
// }
// }
// }
// return ans;
// }
// }
Use this to step through a reusable interview workflow for this problem.
Sort the array in O(n log n), then scan for the missing or unique element by comparing adjacent pairs. Sorting requires O(n) auxiliary space (or O(1) with in-place sort but O(n log n) time remains). The sort step dominates.
Bitwise operations (AND, OR, XOR, shifts) are O(1) per operation on fixed-width integers. A single pass through the input with bit operations gives O(n) time. The key insight: XOR of a number with itself is 0, which eliminates duplicates without extra space.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Wrong move: Zero-count keys stay in map and break distinct/count constraints.
Usually fails on: Window/map size checks are consistently off by one.
Fix: Delete keys when count reaches zero.