Exercises — Z-algorithm — Z-array construction, O(n+m)
3.8.4 · D4· Coding › String Algorithms › Z-algorithm — Z-array construction, O(n+m)
Puri note mein, parent ne jo vocabulary build ki hai use yaad rakho:
- ek string hai jiska length hai, indexed .
- = se shuru hone wale longest run ki length jo string ke start (prefix) ke barabar bhi ho.
- Z-box wo interval hai jiska sabse bada hai jo hum already jaante hain prefix ke barabar hai: .
- Box ke andar ka mirror hai .

Level 1 — Recognition
L1.1 — Ek Z-value padhna
(indices ) ke liye, haath se compute karo. Bilkul clearly batao ki tumne kaunse characters compare kiye aur match kyun ruka.
Recall Solution L1.1
Position se run shuru hoti hai . Prefix shuru hoti hai se.
- Compare vs ✓ (length abhi tak 1)
- Compare vs ✓ (length 2)
- Compare vs ✓ (length 3)
- Next hota , jo exist hi nahi karta → stop.
Toh . Match ruka kyunki hum string ke end se bahar chale gaye, kisi mismatch ki wajah se nahi.
L1.2 — Poora chhota array fill karna
(length 5) ka complete Z-array likho. Convention use karo ki unused hai (dash).
Recall Solution L1.2
aaaaa ki har suffix khud a's ka run hai jo prefix ke barabar hai, lekin sirf utne characters tak jitne bache hain.
| i | 0 | 1 | 2 | 3 | 4 |
|---|---|---|---|---|---|
| s | a | a | a | a | a |
| Z | – | 4 | 3 | 2 | 1 |
: index 1 se 4 characters bache hain, sab a, sab prefix se match karte hain → . Har baad waale index mein ek character kam bachta hai. Answer: .
Level 2 — Application
L2.1 — Box ke saath trace karna
(length 8) ka poora Z-array banao, aur har ke liye batao ki parent ka Case A () apply hua ya Case B ().
Recall Solution L2.1
Start , .
- : → Case A. Compare vs ✗ → . Koi box nahi.
- : → Case A.
abababvs prefixabababsab 6 remaining match karte hain → . Box . - : → Case B. Mirror , , cap , ; while: vs ✗ → .
- : → Case B. , , cap , ; while: ? hum vs test karte hain — range se bahar → stop. . Naya box? , nahi, toh update nahi.
- : → Case B. , , cap , ; while vs ✗ → .
- : → Case B. , , cap , ; while vs range se bahar → stop. .
- : → Case B. , , cap , ; while vs ✗ → .
.
L2.2 — Z se pattern matching
Text , pattern . banao, compute karo kahan (), aur mein 0-indexed positions report karo jahan occur karta hai.
Recall Solution L2.2
, length . Indices:
| i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| S | a | a | b | # | a | a | b | a | b | a | a | b |
Hume chahiye. Text region check karte hain ():
- :
aabvs prefixaab✓✓✓, phir vs ✗ → . Hit. - :
aabvsaab✓✓✓, phir end se bahar → . Hit. - Baaki sab positions dete hain.
Position convert karo :
- -position .
- -position .
Toh , -positions par occur karta hai. Check: ✓, ✓.
Level 3 — Analysis
L3.1 — Ek comparison "free" kab hota hai?
(L2.1) ke trace mein, par humne set kiya. while loop ne wahaan actually kitne character comparisons kiye, aur kyun? se contrast karo.
Recall Solution L3.1
par: cap , toh loop entered hua ke saath. Phir isne s[4] == s[8] test kiya — lekin range se bahar hai, toh while condition i+Z[i] < n turant false hai. Zero character comparisons. Value 4 mirror knowledge se copy ki gayi, bilkul free mein verify hui.
par (Case A): humne se start kiya aur scratch se compare karna pada: 6 successful matches phir end se bahar → 6 character comparisons. Yahi "real work" hai jisne ko se tak push kiya.
Key insight: par free copy exactly wahi reuse hai jo box humein dilata hai — mirror par ne already un matches ke liye pay kar diya tha.
L3.2 — B1 aur B2 mein farq karna
mein (parent ke full trace se), aur ko sub-case B1 (mirror box ke andar fit hota hai, koi extension nahi) ya B2 (mirror edge tak pahunchta hai, extend karna padta hai) classify karo. Numbers se justify karo.
Recall Solution L3.2
Jab hum inhe process karte hain, box hai.
- : mirror , . Box edge distance . Kya ? ✓ → B1. Mirror ka match (length 1) aur uska terminating mismatch dono strictly box ke andar hain, toh bina kisi comparison ke copy ho jaata hai.
- : mirror , . Edge distance . Kya ? Haan → yeh bhi B1 hai ( fit ho jaata hai). Hum copy karte hain;
whileek baar vs test karta hai aur fail hota hai, kuch add nahi hota.
Yahaan koi true B2 nahi hai, kyunki koi mirror value box boundary tak pahunchi hi nahi. B2 ka example: abababab mein par, edge , toh isne cap hit kiya — yahi B2 shape hai (humne min pe rely kiya taaki unchecked territory claim na ho jaaye).
Level 4 — Synthesis
L4.1 — Distinct substrings count karein? Nahi — prefix occurrences count karein
ke single Z-array ka use karke determine karo ki prefix ab (length 2) mein substring ke roop mein kitni baar occur karta hai. Rule explain karo.
Recall Solution L4.1
Length ka prefix position se start hota hua occur karta hai iff (wahaan se kam se kam lamba match shuru hota hai). Hum position ko bhi hamesha count karte hain.
ababa ke liye build karo:
- : vs ✗ → .
- :
abavsaba→ 3 matches, end se bahar → . Box . - : , mirror , , cap , ; vs ✗ → .
- : , mirror , , cap , ; while vs range se bahar → .
. Positions count karo (including 0) jahan : position (prefix khud), (). Total occurrences of ab. Aankhon se check karo: ababa → ab indices aur par. ✔
L4.2 — Z se longest border
Jo prefix ka suffix bhi ho (ek "border") use Z se padha ja sakta hai. (length 10) ke liye, longest proper border ki length dhundho. Rule: length ka border exist karta hai iff koi index hai jahan aur .
Recall Solution L4.1 → L4.2
Hume wo positions chahiye jahan match exactly end tak jaata ho: .
Relevant Z-values haath se compute karo:
- : run
abcabvs prefixabcab→ 5 match karta hai (s[5..9]=abcab, prefixabcab), phir end se bahar → , aur ✓. Border length . - Koi longer? Length ke border ko with chahiye hoga; lekin → . Nahi.
Longest proper border length (abcab). Check: prefix abcab = suffix abcab of abcababcab. ✔ Yahi exactly woh information hai jo KMP failure function store karta hai; Z iske liye ek alternative route deta hai.
Level 5 — Mastery
L5.1 — Prove karo ki box kabhi shrink nahi karta
Rigorously argue karo ki parent ke algorithm mein, value saari iterations mein non-decreasing rehti hai. Phir iska use karke total while-loop iterations bound karo.
Recall Solution L5.1
sirf box-update line ke andar change hota hai, jo fire karta hai iff , aur set karta hai . Apne hi guard se, naya strictly puraane se bada hai. Koi doosri line ko touch nahi karti. Isliye (weakly) non-decreasing hai — actually strictly increasing jab bhi change hota hai. ∎
while work ka bound. Har successful while iteration position par ek character match karti hai jo puraane se bahar tha (positions already known the, toh extension sirf ke baad hoti hai), aur phir use cover karne ke liye advance hota hai. Kyunki se start hota hai, har success par strictly increase karta hai, aur hamesha rehta hai, toh poore run mein at most successful while iterations hoti hain. Har mein at most ek failing while test bhi hota hai (woh mismatch jo uska loop end karta hai), total additional constant-cost tests deta hai. Total: . Pattern matching ke liye concatenation ke saath combine karo → .
L5.2 — Degenerate aur edge inputs
Har edge case ke liye Z-array batao aur explain karo: (a) empty string, (b) single character x, (c) do identical characters yy, (d) ek letter ka alphabet baar repeat k times (general formula).
Recall Solution L5.2
- (a) empty string : array empty hai, . Process karne ke liye koi positions nahi; loop
for i in 1..n-1zero baar chalta hai. Valid. - (b)
x, : (sirf , unused). Loop se start hota hai, toh kabhi nahi chalta. Match karne ke liye koi proper suffix nahi hai. - (c)
yy, : , Case A, vs ✓, phir end se bahar → . Toh . - (d)
a^k(letter baar repeat): L1.2 pattern se, for . Formula: . Yeh naive algorithm ke liye worst case hai () lekin box-based algorithm fir bhi mein run karta hai: box par poori tail cover karne ke liye jump karta hai, aur har baad wala ek free B1 copy hota hai.
Recall Aage kahan jaayein
- Strong feel ho raha hai? Z ko KMP failure function se compare karo — dono different mechanics se closely related border information compute karte hain.
- Prefix matching ki jagah hashing se matching ke liye, String Hashing dekho.
- Is reuse trick ka palindrome-flavored cousin: Manacher's Algorithm.
- Heavier full-text index structures: Suffix Array, Suffix Automaton.
- Linear-time proof style generalizes: Amortized Analysis.
- Core ka Hinglish walkthrough: 3.8.04 Z-algorithm — Z-array construction, O(n+m) (Hinglish).