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.
Move from brute-force thinking to an efficient approach using array strategy.
Given the array favoriteCompanies where favoriteCompanies[i] is the list of favorites companies for the ith person (indexed from 0).
Return the indices of people whose list of favorite companies is not a subset of any other list of favorites companies. You must return the indices in increasing order.
Example 1:
Input: favoriteCompanies = [["leetcode","google","facebook"],["google","microsoft"],["google","facebook"],["google"],["amazon"]] Output: [0,1,4] Explanation: Person with index=2 has favoriteCompanies[2]=["google","facebook"] which is a subset of favoriteCompanies[0]=["leetcode","google","facebook"] corresponding to the person with index 0. Person with index=3 has favoriteCompanies[3]=["google"] which is a subset of favoriteCompanies[0]=["leetcode","google","facebook"] and favoriteCompanies[1]=["google","microsoft"]. Other lists of favorite companies are not a subset of another list, therefore, the answer is [0,1,4].
Example 2:
Input: favoriteCompanies = [["leetcode","google","facebook"],["leetcode","amazon"],["facebook","google"]] Output: [0,1] Explanation: In this case favoriteCompanies[2]=["facebook","google"] is a subset of favoriteCompanies[0]=["leetcode","google","facebook"], therefore, the answer is [0,1].
Example 3:
Input: favoriteCompanies = [["leetcode"],["google"],["facebook"],["amazon"]] Output: [0,1,2,3]
Constraints:
1 <= favoriteCompanies.length <= 1001 <= favoriteCompanies[i].length <= 5001 <= favoriteCompanies[i][j].length <= 20favoriteCompanies[i] are distinct.favoriteCompanies[i] != favoriteCompanies[j].Problem summary: Given the array favoriteCompanies where favoriteCompanies[i] is the list of favorites companies for the ith person (indexed from 0). Return the indices of people whose list of favorite companies is not a subset of any other list of favorites companies. You must return the indices in increasing order.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Array · Hash Map
[["leetcode","google","facebook"],["google","microsoft"],["google","facebook"],["google"],["amazon"]]
[["leetcode","google","facebook"],["leetcode","amazon"],["facebook","google"]]
[["leetcode"],["google"],["facebook"],["amazon"]]
Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #1452: People Whose List of Favorite Companies Is Not a Subset of Another List
class Solution {
public List<Integer> peopleIndexes(List<List<String>> favoriteCompanies) {
int n = favoriteCompanies.size();
Map<String, Integer> d = new HashMap<>();
int idx = 0;
Set<Integer>[] nums = new Set[n];
Arrays.setAll(nums, i -> new HashSet<>());
for (int i = 0; i < n; ++i) {
var ss = favoriteCompanies.get(i);
for (var s : ss) {
if (!d.containsKey(s)) {
d.put(s, idx++);
}
nums[i].add(d.get(s));
}
}
List<Integer> ans = new ArrayList<>();
for (int i = 0; i < n; ++i) {
boolean ok = true;
for (int j = 0; j < n && ok; ++j) {
if (i != j && nums[j].containsAll(nums[i])) {
ok = false;
}
}
if (ok) {
ans.add(i);
}
}
return ans;
}
}
// Accepted solution for LeetCode #1452: People Whose List of Favorite Companies Is Not a Subset of Another List
func peopleIndexes(favoriteCompanies [][]string) (ans []int) {
n := len(favoriteCompanies)
d := make(map[string]int)
idx := 0
nums := make([]map[int]struct{}, n)
for i := 0; i < n; i++ {
nums[i] = make(map[int]struct{})
for _, s := range favoriteCompanies[i] {
if _, ok := d[s]; !ok {
d[s] = idx
idx++
}
nums[i][d[s]] = struct{}{}
}
}
check := func(a, b map[int]struct{}) bool {
for x := range a {
if _, ok := b[x]; !ok {
return false
}
}
return true
}
for i := 0; i < n; i++ {
ok := true
for j := 0; j < n && ok; j++ {
if i != j && check(nums[i], nums[j]) {
ok = false
}
}
if ok {
ans = append(ans, i)
}
}
return
}
# Accepted solution for LeetCode #1452: People Whose List of Favorite Companies Is Not a Subset of Another List
class Solution:
def peopleIndexes(self, favoriteCompanies: List[List[str]]) -> List[int]:
idx = 0
d = {}
n = len(favoriteCompanies)
nums = [set() for _ in range(n)]
for i, ss in enumerate(favoriteCompanies):
for s in ss:
if s not in d:
d[s] = idx
idx += 1
nums[i].add(d[s])
ans = []
for i in range(n):
if not any(i != j and (nums[i] & nums[j]) == nums[i] for j in range(n)):
ans.append(i)
return ans
// Accepted solution for LeetCode #1452: People Whose List of Favorite Companies Is Not a Subset of Another List
struct Solution;
use std::collections::HashSet;
impl Solution {
fn people_indexes(favorite_companies: Vec<Vec<String>>) -> Vec<i32> {
let people: Vec<HashSet<String>> = favorite_companies
.into_iter()
.map(|v| v.into_iter().collect())
.collect();
let n = people.len();
let mut res = vec![];
'outer: for i in 0..n {
for j in 0..n {
if i != j && people[i].is_subset(&people[j]) {
continue 'outer;
}
}
res.push(i as i32);
}
res
}
}
#[test]
fn test() {
let favorite_companies = vec_vec_string![
["leetcode", "google", "facebook"],
["google", "microsoft"],
["google", "facebook"],
["google"],
["amazon"]
];
let res = vec![0, 1, 4];
assert_eq!(Solution::people_indexes(favorite_companies), res);
let favorite_companies = vec_vec_string![
["leetcode", "google", "facebook"],
["leetcode", "amazon"],
["facebook", "google"]
];
let res = vec![0, 1];
assert_eq!(Solution::people_indexes(favorite_companies), res);
let favorite_companies = vec_vec_string![["leetcode"], ["google"], ["facebook"], ["amazon"]];
let res = vec![0, 1, 2, 3];
assert_eq!(Solution::people_indexes(favorite_companies), res);
}
// Accepted solution for LeetCode #1452: People Whose List of Favorite Companies Is Not a Subset of Another List
function peopleIndexes(favoriteCompanies: string[][]): number[] {
const n = favoriteCompanies.length;
const d: Map<string, number> = new Map();
let idx = 0;
const nums: Set<number>[] = Array.from({ length: n }, () => new Set<number>());
for (let i = 0; i < n; i++) {
for (const s of favoriteCompanies[i]) {
if (!d.has(s)) {
d.set(s, idx++);
}
nums[i].add(d.get(s)!);
}
}
const check = (a: Set<number>, b: Set<number>): boolean => {
for (const x of a) {
if (!b.has(x)) {
return false;
}
}
return true;
};
const ans: number[] = [];
for (let i = 0; i < n; i++) {
let ok = true;
for (let j = 0; j < n && ok; j++) {
if (i !== j && check(nums[i], nums[j])) {
ok = false;
}
}
if (ok) {
ans.push(i);
}
}
return ans;
}
Use this to step through a reusable interview workflow for this problem.
Two nested loops check every pair or subarray. The outer loop fixes a starting point, the inner loop extends or searches. For n elements this gives up to n²/2 operations. No extra space, but the quadratic time is prohibitive for large inputs.
Most array problems have an O(n²) brute force (nested loops) and an O(n) optimal (single pass with clever state tracking). The key is identifying what information to maintain as you scan: a running max, a prefix sum, a hash map of seen values, or two pointers.
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.