Want Help Cracking FAANG?

(Then click this)

×
Back to Question Bank

1773. Count Items Matching a Rule - Leetcode Solution

Problem Description

You are given a list of items, where each item is represented as a list of three strings: [type, color, name]. You are also given a ruleKey and a ruleValue. The ruleKey can be one of "type", "color", or "name". Your task is to count how many items in the list match the given rule, i.e., where the value corresponding to the ruleKey is equal to ruleValue.

For example, given items = [["phone","blue","pixel"], ["computer","silver","lenovo"], ["phone","gold","iphone"]], ruleKey = "type", and ruleValue = "phone", you should return 2 because two items have type equal to "phone".

Key constraints:

  • Each item contains exactly three elements in the order: type, color, name.
  • Only count items where the value for the given ruleKey matches ruleValue.
  • No elements are reused or modified; simply count the matches.

Thought Process

The problem is essentially about filtering a list of items based on a specific attribute and value. The first idea is to check each item, see if it matches the rule, and count it. Since each item is a list of three strings, and the ruleKey tells us which position to check, we need a way to map ruleKey to the correct index in the item list.

A brute-force approach would be to loop through every item, check the value at the right index, and increment a counter if it matches. There isn’t an obvious way to optimize further since the input size is small and the task is simple filtering. The main thing to get right is the mapping from ruleKey to the correct index: "type" is index 0, "color" is index 1, "name" is index 2.

Solution Approach

Here’s a step-by-step guide to solving the problem:

  1. Map the ruleKey to the correct index:
    • If ruleKey is "type", use index 0.
    • If ruleKey is "color", use index 1.
    • If ruleKey is "name", use index 2.
  2. Iterate through the items list:
    • For each item, check if the value at the mapped index matches ruleValue.
    • If it matches, increment a counter.
  3. Return the counter:
    • After checking all items, return the total count of matches.

This approach is direct and efficient for the problem constraints. We use a dictionary or simple if-else statements to map the ruleKey to the appropriate index for clarity and maintainability.

Example Walkthrough

Let's walk through the example:
Input:

  • items = [["phone","blue","pixel"], ["computer","silver","lenovo"], ["phone","gold","iphone"]]
  • ruleKey = "type"
  • ruleValue = "phone"
Step-by-step:
  1. Map ruleKey = "type" to index 0.
  2. Iterate through items:
    • Item 1: ["phone","blue","pixel"] — item[0] = "phone" (matches), count = 1
    • Item 2: ["computer","silver","lenovo"] — item[0] = "computer" (does not match), count = 1
    • Item 3: ["phone","gold","iphone"] — item[0] = "phone" (matches), count = 2
  3. Return 2 as the final answer.

The process checks each item’s type and counts the matches, resulting in the correct answer.

Code Implementation

class Solution:
    def countMatches(self, items, ruleKey, ruleValue):
        # Map ruleKey to index
        key_to_index = {"type": 0, "color": 1, "name": 2}
        idx = key_to_index[ruleKey]
        count = 0
        for item in items:
            if item[idx] == ruleValue:
                count += 1
        return count
      
class Solution {
public:
    int countMatches(vector<vector<string>>& items, string ruleKey, string ruleValue) {
        int idx = 0;
        if (ruleKey == "color") idx = 1;
        else if (ruleKey == "name") idx = 2;
        int count = 0;
        for (const auto& item : items) {
            if (item[idx] == ruleValue) {
                count++;
            }
        }
        return count;
    }
};
      
class Solution {
    public int countMatches(List<List<String>> items, String ruleKey, String ruleValue) {
        int idx = 0;
        if (ruleKey.equals("color")) idx = 1;
        else if (ruleKey.equals("name")) idx = 2;
        int count = 0;
        for (List<String> item : items) {
            if (item.get(idx).equals(ruleValue)) {
                count++;
            }
        }
        return count;
    }
}
      
var countMatches = function(items, ruleKey, ruleValue) {
    let keyToIndex = { "type": 0, "color": 1, "name": 2 };
    let idx = keyToIndex[ruleKey];
    let count = 0;
    for (let item of items) {
        if (item[idx] === ruleValue) {
            count++;
        }
    }
    return count;
};
      

Time and Space Complexity

Brute-force Approach:

  • Time Complexity: O(n), where n is the number of items. We check each item exactly once.
  • Space Complexity: O(1), since we only use a few variables for counting and mapping.
Optimized Approach:
  • This is already optimal for the problem's constraints. There’s no way to avoid checking each item at least once.

The mapping from ruleKey to index is constant time, and the single pass through the items ensures optimal efficiency.

Summary

The solution to the "Count Items Matching a Rule" problem is straightforward: map the ruleKey to the correct index, iterate through all items, and count those that match the ruleValue. The approach is efficient (O(n) time, O(1) space), easy to implement, and leverages simple control flow and data mapping. The key insight is recognizing the fixed structure of each item, which allows direct indexing and eliminates unnecessary complexity.