Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# 1967. Number of Strings That Appear as Substrings in Word

[LeetCode Link](https://leetcode.com/problems/number-of-strings-that-appear-as-substrings-in-word/)

Difficulty: Easy
Topics: Array, String
Acceptance Rate: 84.1%

## Hints

### Hint 1

This problem is essentially a counting problem layered on top of a substring-membership test. Ask yourself: for a single pattern, how would you decide whether it appears somewhere inside `word`? Once you can answer that for one pattern, the rest is just repetition.

### Hint 2

The core operation you need is "does string `B` contain string `A` as a contiguous block of characters?" This is the classic *substring search* operation. Most languages give it to you directly (`strings.Contains` in Go), so you don't need to hand-roll any matching algorithm here. Think about wrapping that check in a loop.

### Hint 3

Iterate over every pattern, run the substring check against `word`, and increment a counter each time the check succeeds. There is no trick beyond this — the constraints are tiny (at most 100 patterns, each at most 100 characters, `word` at most 100 characters), so a straightforward scan is more than fast enough. Don't over-engineer it.

## Approach

The task asks for the number of strings in `patterns` that occur as a substring of `word`.

The algorithm is direct:

1. Initialize a counter `count = 0`.
2. For each `p` in `patterns`, test whether `p` is a substring of `word`.
3. If it is, increment `count`.
4. Return `count`.

In Go, step 2 is exactly `strings.Contains(word, p)`, which returns `true` when `p` appears as a contiguous sequence inside `word`. Under the hood this is an efficient substring search (Go uses a Rabin–Karp / Boyer–Moore-style implementation), but conceptually you can think of it as sliding `p` across `word` and comparing.

**Walking through Example 1:** `patterns = ["a","abc","bc","d"]`, `word = "abc"`.

- `"a"` → contained in `"abc"` → count = 1
- `"abc"` → contained in `"abc"` → count = 2
- `"bc"` → contained in `"abc"` → count = 3
- `"d"` → not contained → count stays 3

Result: `3`, which matches the expected output.

Why it works: "appears as a substring" is precisely the membership relation that `strings.Contains` tests, and counting independent successes is just a running tally. Because each pattern is tested independently, duplicates in `patterns` are each counted separately (see Example 3, where `["a","a","a"]` yields `3`).

If you wanted to implement the substring check yourself, you would, for each starting index `i` in `word`, compare `word[i:i+len(p)]` against `p` and stop at the first match. That is the naive O(n·m) check, and it is perfectly acceptable at these constraints.

## Complexity Analysis

Let `k` be the number of patterns, `m` the maximum pattern length, and `n` the length of `word`.

Time Complexity: O(k · n · m) in the worst case — for each of the `k` patterns, the substring search may scan up to `n` starting positions, each comparing up to `m` characters. With the given limits (k, m, n ≤ 100) this is at most on the order of 10^6 character comparisons, effectively instant. (Go's optimized `strings.Contains` is typically closer to O(k · (n + m)).)

Space Complexity: O(1) — only a single integer counter is used beyond the input.

## Edge Cases

- **Pattern longer than `word`:** A pattern with more characters than `word` can never be a substring, so the check correctly returns `false`. The constraints allow patterns up to length 100 and `word` as short as length 1, so this genuinely happens.
- **Duplicate patterns:** `["a","a","a"]` must count each occurrence, giving `3`, not `1`. Because we test each list element independently, duplicates are handled naturally — do not deduplicate.
- **No matches at all:** Every pattern failing the check should return `0`, not an error. The counter simply stays at its initial value.
- **All patterns match:** When every pattern is found, the answer equals `len(patterns)`.
- **Single-character patterns and word:** The smallest inputs (`word` of length 1, patterns of length 1) still work because `strings.Contains` treats single characters as ordinary substrings.
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
number: "1967"
frontend_id: "1967"
title: "Number of Strings That Appear as Substrings in Word"
slug: "number-of-strings-that-appear-as-substrings-in-word"
difficulty: "Easy"
topics:
- "Array"
- "String"
acceptance_rate: 8412.8
is_premium: false
created_at: "2026-06-29T05:10:21.203952+00:00"
fetched_at: "2026-06-29T05:10:21.203952+00:00"
link: "https://leetcode.com/problems/number-of-strings-that-appear-as-substrings-in-word/"
date: "2026-06-29"
---

# 1967. Number of Strings That Appear as Substrings in Word

Given an array of strings `patterns` and a string `word`, return _the**number** of strings in _`patterns` _that exist as a**substring** in _`word`.

A **substring** is a contiguous sequence of characters within a string.



**Example 1:**


**Input:** patterns = ["a","abc","bc","d"], word = "abc"
**Output:** 3
**Explanation:**
- "a" appears as a substring in "_a_ bc".
- "abc" appears as a substring in "_abc_ ".
- "bc" appears as a substring in "a _bc_ ".
- "d" does not appear as a substring in "abc".
3 of the strings in patterns appear as a substring in word.


**Example 2:**


**Input:** patterns = ["a","b","c"], word = "aaaaabbbbb"
**Output:** 2
**Explanation:**
- "a" appears as a substring in "a _a_ aaabbbbb".
- "b" appears as a substring in "aaaaabbbb _b_ ".
- "c" does not appear as a substring in "aaaaabbbbb".
2 of the strings in patterns appear as a substring in word.


**Example 3:**


**Input:** patterns = ["a","a","a"], word = "ab"
**Output:** 3
**Explanation:** Each of the patterns appears as a substring in word "_a_ b".




**Constraints:**

* `1 <= patterns.length <= 100`
* `1 <= patterns[i].length <= 100`
* `1 <= word.length <= 100`
* `patterns[i]` and `word` consist of lowercase English letters.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package main

// Problem 1967: Number of Strings That Appear as Substrings in Word
//
// Approach: For each pattern, check whether it appears as a contiguous
// substring of word using strings.Contains, and count the successes.
// The constraints are tiny (<= 100 patterns, lengths <= 100), so a direct
// scan is optimal in practice.

import "strings"

func numOfStrings(patterns []string, word string) int {
count := 0
for _, p := range patterns {
if strings.Contains(word, p) {
count++
}
}
return count
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package main

import "testing"

func TestSolution(t *testing.T) {
tests := []struct {
name string
patterns []string
word string
expected int
}{
{
name: "example 1: some patterns match",
patterns: []string{"a", "abc", "bc", "d"},
word: "abc",
expected: 3,
},
{
name: "example 2: repeated characters in word",
patterns: []string{"a", "b", "c"},
word: "aaaaabbbbb",
expected: 2,
},
{
name: "example 3: duplicate patterns counted separately",
patterns: []string{"a", "a", "a"},
word: "ab",
expected: 3,
},
{
name: "edge case: no pattern matches",
patterns: []string{"x", "yz", "qq"},
word: "abc",
expected: 0,
},
{
name: "edge case: pattern longer than word",
patterns: []string{"abcd", "ab"},
word: "abc",
expected: 1,
},
{
name: "edge case: single-character word and patterns",
patterns: []string{"a", "b"},
word: "a",
expected: 1,
},
{
name: "edge case: all patterns match",
patterns: []string{"ab", "bc", "abc"},
word: "abc",
expected: 3,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := numOfStrings(tt.patterns, tt.word)
if result != tt.expected {
t.Errorf("numOfStrings(%v, %q) = %d, want %d",
tt.patterns, tt.word, result, tt.expected)
}
})
}
}