3.7.10 · D3 · Coding › Algorithm Paradigms › DP problems — Longest Common Subsequence (LCS)
Intuition Yeh page kis liye hai
Parent note ne recurrence sikhaya tha. Yahan hum usse har tarah ke input ke against stress-test karte hain jo duniya de sakti hai — normal strings, empty strings, no-overlap strings, all-same strings, ties, aur ek real word problem. Agar tum neeche har cell walk kar sako, toh LCS ka koi bhi exam version tumhe surprise nahi kar sakta.
Shuru karne se pehle, ek reminder us machine ka jo hum use kar rahe hain (parent se). Hum likhte hain X = x 1 x 2 … x m aur Y = y 1 y 2 … y n , aur L ( i , j ) hai LCS length X ke pehle i letters aur Y ke pehle j letters ki.
Har LCS problem in cells mein se kisi ek mein aati hai. Neeche ke examples us cell ke saath label kiye hain jisme woh fit hote hain, aur milke yeh sab ko cover karte hain.
#
Cell (case class)
Kya special hai
Example
C1
Typical overlap
Dono strings non-empty, partial match with gaps
Ex. 1
C2
Zero input (empty string)
Ek string "" hai
Ex. 2
C3
No common characters
Disjoint alphabets → answer 0
Ex. 3
C4
Identical strings
Upper bound: LCS = poori string
Ex. 4
C5
Ek doosre ki subsequence hai
LCS = poori choti wali
Ex. 5
C6
Ties / multiple valid LCS
Traceback branches, kai answers
Ex. 6
C7
Repeated characters trap
Same letter kai baar aata hai — order phir bhi rule karta hai
Ex. 7
C8
Real-world word problem
Do playlists / DNA / diff
Ex. 8
C9
Exam twist
LCS vs substring same input par
Ex. 9
Recall Yeh nau hi kyun, zyada kyun nahi?
Recurrence mein exactly teen branches hain (base, match, mismatch). "Har scenario" ka matlab hai har degenerate condition mein har branch ko exercise karna: empty input sirf base row hit karta hai (C2), disjoint input sirf mismatch hit karta hai (C3), identical input sirf match hit karta hai (C4). Baaki combinations hain. Worry karne ke liye koi chautha behavior nahi hai.
Koi bhi LCS input in mein se kisi ek tak reduce hota hai ::: haan — base, all-match, all-miss, ya mixture; matrix har ek ko cover karta hai.
ABCBDAB vs BDCAB
LCS length nikalo.
Forecast: eyeball karo — dono se order mein kaunse letters rakh sakte ho? Apna guess likho (main predict karta hoon ek chota number, 3 ya 4) padhne se pehle.
Step 1 — table set up karo. X = ABCBDAB (m = 7 ), Y = BDCAB (n = 5 ). Ek ( 8 ) × ( 6 ) grid banao jiska row 0 aur column 0 sab zeros hain.
Yeh step kyun? Extra zero border base case L ( 0 , j ) = L ( i , 0 ) = 0 encode karta hai: empty prefix se compare karne par kuch nahi milta. Figure mein grey border dekho.
Step 2 — row by row "match→diagonal+1, miss→max" se fill karo. Har cell sirf teen neighbours dekhti hai: up-left (diagonal), up, left.
Yeh step kyun? Woh sirf wahi chote subproblems hain jo recurrence reference karta hai. Figure mein green cells matches hain (diagonal + 1); plain cells ne max ( up , left ) inherit kiya.
Step 3 — corner padho. Bottom-right cell mein L ( 7 , 5 ) = 4 hai.
Yeh step kyun? L ( m , n ) by definition poori strings ka LCS hai.
Answer: length 4 (jaise BCAB ya BDAB).
Verify: BCAB AB C BDAB mein aur BDCAB mein milta hai → B D C A B , dono order mein. ✅ Length corner se match karti hai. Length kabhi min ( m , n ) = 5 se zyada nahi ho sakti, aur 4 ≤ 5 — sane hai.
HELLO vs ""
LCS kya hai?
Forecast: agar ek dost ki cartoon list empty hai, toh dono ne kitne cartoons dekhe hain?
Step 1 — base case directly apply karo. Yahan n = 0 hai, toh hum kabhi column 0 se bahar nahi jaate. Jo bhi cell padh sakte hain woh L ( i , 0 ) = 0 hai.
Yeh step kyun? Empty prefix share karne ke liye koi characters nahi deta; recurrence ka base branch fire karta hai aur kuch aur kabhi nahi karta.
Answer: length 0 , LCS empty string "" hai.
Verify: "" se characters delete karke non-empty common subsequence nahi ban sakti — rakhne ke liye kuch hai hi nahi. Poora grid zero border hai. ✅ Degenerate case, sirf border se handle ho gaya.
Common mistake Empty case bhoolna real code crash karta hai
Agar tum loop karo for i in range(1, m+1) lekin m = 0 hai, toh loop body kabhi nahi chalti aur tum correctly L[0][0]=0 return karte ho — sirf isliye kyunki zero border exist karta hai. Border skip karo aur tum out of bounds index karoge. Border decoration nahi hai; yeh hi base case hai.
ABC vs XYZ
LCS nikalo.
Forecast: alphabets bilkul overlap nahi karte. Padhne se pehle guess karo.
Step 1 — har comparison ek mismatch hai. Koi x i kisi y j ke equal nahi, toh match branch kabhi fire nahi karta. Har interior cell max ( up , left ) leta hai.
Yeh step kyun? Jab diagonal + 1 kabhi nahi mila, toh kisi bhi cell ki sabse badi value jo woh inherit kar sakti hai woh uske border ki sabse badi value hai — jo 0 hai.
Step 2 — zeros propagate karo. max ( 0 , 0 ) = 0 poora grid fill karta hai.
Yeh step kyun? Tum sirf match par 1 add karke 0 se aage badh sakte ho; zero matches ke saath kuch nahi badhta.
Answer: length 0 .
Verify: kisi bhi common subsequence ko dono strings mein ek letter chahiye; koi nahi hai, toh 0 forced hai. ✅ Yeh LCS ki lower bound hai.
MATCH vs MATCH
LCS nikalo.
Forecast: agar strings same hain, toh sabse badi shared subsequence kya ho sakti hai?
Step 1 — diagonal sab matches hai. Main diagonal par position-by-position compare karo: x 1 = y 1 , x 2 = y 2 , … har pair match karta hai.
Yeh step kyun? Equal strings ka matlab hai x k = y k sab k ke liye, toh match branch poore diagonal par fire karta hai, har fire + 1 add karta hai.
Step 2 — additions count karo. Paanch matches → paanch + 1 s → L ( 5 , 5 ) = 5 .
Yeh step kyun? Diagonal walk L ( k , k ) = 1 + L ( k − 1 , k − 1 ) telescope karta hai: L ( 5 , 5 ) = 5 .
Answer: length 5 , LCS = MATCH khud.
Verify: LCS length kabhi min ( m , n ) = 5 se zyada nahi ho sakti; yahan hum exactly woh ceiling hit karte hain, jaise identical strings ko karna hi chahiye. ✅ Yeh upper bound hai: LCS = length jab X = Y ho.
ACE vs ABCDE
LCS nikalo.
Forecast: ACE ko ABCDE se B aur D skip karke spell kar sakte hain. Toh LCS kya hai?
Step 1 — containment recognize karo. Choti string ka har letter, order mein, lambi string ke andar milta hai.
Yeh step kyun? Agar ACE already ABCDE ki subsequence hai, toh ACE dono mein common hai, toh LCS kam se kam ∣ ACE∣ = 3 hai.
Step 2 — cap lagao. LCS choti length, min ( 3 , 5 ) = 3 , se zyada nahi ho sakta.
Yeh step kyun? Tum choti string ke paas jitne letters hain usse zyada kabhi nahi rakh sakte.
Answer: length 3 , LCS = ACE.
Verify: A_C_E ABCDE ke andar baitha hai; ACE khud poora hai. Dono directions 3 par agree karte hain. ✅ Jab bhi ek string doosri ki subsequence hoti hai, LCS = poori choti wali.
ABCBDAB vs BDCAB — ek string recover karo
Ex. 1 ke same numbers, lekin ab actual LCS trace back karo aur notice karo yeh unique nahi hai.
Forecast: agar do neighbours (up aur left) equal hain, toh kaunsa follow karte hain? Kya choice length ke liye matter karti hai?
Step 1 — corner se start karo L ( 7 , 5 ) = 4 aur backwards chalo.
Yeh step kyun? Corner answer hai; traceback poochta hai "kaunse neighbour ne mujhe banaya?"
Step 2 — match par, diagonal jao aur letter record karo. Jab x i = y j , yeh cell 1 + diagonal thi, toh woh shared letter LCS ka hissa hai.
Yeh step kyun? Value literally diagonal + 1 se aayi; usse follow karne par woh character milta hai jo responsible tha.
Step 3 — mismatch par, up/left mein se bade ki taraf jao; tie par, dono kaam karte hain. Tie ka matlab do different equal-length subsequences exist karti hain.
Yeh step kyun? Dono parents same optimal value carry karte hain, toh dono valid (equally long) LCS tak le jaate hain — length identical hai, sirf string alag hoti hai.
Answer: length 4 ; do valid strings hain BCAB (red path) aur BDAB (blue path).
Verify: BCAB aur BDAB dono length 4 hain aur dono dono inputs mein order mein milti hain (BDCAB mein B D C A B → B_CAB aur BD_AB pick karo). Ties kabhi length nahi badlate, sirf witness badlata hai. ✅
AAAA vs AA
LCS nikalo.
Forecast: letter A bahut zyada repeat hota hai. Kya answer 4 hai? 2? Kuch aur? Order aur availability dono matter karte hain.
Step 1 — tum utne hi As match kar sakte ho jitne poor string ke paas hain. Y=AAsirf doAs supply karta hai. *Yeh step kyun?* Har matched pair *dono* strings se ek character consume karta hai (diagonal move). Choti string do matches ke baad A`s se bahar ho jaati hai.
Step 2 — min par cap lagao. Do matches → L ( 4 , 2 ) = 2 .
Yeh step kyun? min ( m , n ) = min ( 4 , 2 ) = 2 ; repetition woh characters create nahi kar sakti jo choti string ke paas nahi hain.
Answer: length 2 , LCS = AA.
Verify: AAAA se do As delete karo → AA; AA poora Y hai. Dono 2 dete hain. ✅ Repeats LCS inflate nahi karte — shorter supply bottleneck hai.
Worked example Do doston ki cartoon playlists
Aki ne, order mein, dekha: Tom Jerry Doraemon Shinchan Pokemon.
Bina ne, order mein, dekha: Jerry Shinchan Pokemon Tom.
Woh sabse lamba playlist kaunsa hai jisme dono ne same order mein cartoons dekhe (skips allowed, reshuffling nahi)?
Forecast: clearly kuch titles share hain, lekin order constraint karta hai. Length guess karo.
Step 1 — har cartoon ko ek "letter" samjho. Encode karo
X = [Tom, Jerry, Doraemon, Shinchan, Pokemon], Y = [Jerry, Shinchan, Pokemon, Tom].
Yeh step kyun? LCS ko parwah nahi ki "letters" poore words hain — woh tokens ko equality aur order ke liye compare karta hai. Ek diff tool bilkul aise hi kisi file ki lines treat karta hai.
Step 2 — tokens par recurrence chalao. Matches hote hain Jerry, Shinchan, Pokemon, Tom par. Lekin Tom Aki ki list mein pehle hai aur Bina ki list mein aakhir mein — isko use karna Pokemon ke baad order tod dega.
Yeh step kyun? Order hi poora point hai; DP automatically out-of-order matches refuse karta hai kyunki woh sirf up/left/diagonal move karta hai.
Step 3 — sabse lamba in-order chain hai Jerry → Shinchan → Pokemon.
Yeh step kyun? Yeh teen dono lists mein us order mein milte hain; Tom dono ke liye order mein append nahi ho sakta, toh drop ho jaata hai.
Answer: length 3 — shared in-order playlist hai Jerry, Shinchan, Pokemon.
Verify: Aki ki list mein Jerry(2) < Shinchan(4) < Pokemon(5) ✅ increasing; Bina ki list mein Jerry(1) < Shinchan(2) < Pokemon(3) ✅ increasing. Tom add karna ek list mein order fail karta hai, toh 3 maximal hai. Yeh exactly diff lines par hai. ✅
ABCBDAB vs BDCAB — DONO answers do
Longest Common Subsequence length AUR Longest Common Substring length report karo, aur gap explain karo.
Forecast: substring contiguous honi chahiye; subsequence skip kar sakti hai. Kaunsa bada hai, aur kitna?
Step 1 — LCS (subsequence). Ex. 1 se, gaps allowed → length 4 (BCAB).
Yeh step kyun? Mismatch branch max ( up , left ) rakhta hai, toh progress mismatch survive karta hai — yahi cheez humein gaps jump karne deti hai.
Step 2 — LCSubstring ek alag recurrence use karta hai. Substrings ke liye, mismatch 0 par reset hota hai , aur answer sab cells par maximum hai, corner nahi:
S ( i , j ) = { 1 + S ( i − 1 , j − 1 ) 0 x i = y j x i = y j , answer = i , j max S ( i , j ) .
Yeh step kyun? Contiguity ka matlab ek mismatch poora run todh deta hai; tum up/left se inherit nahi kar sakte.
Step 3 — dono mein sabse lamba contiguous run dhundo. AB pieces (...DABof X aurBDC**AB**`` of Y mein) aur CB extend nahi karte; sabse accha contiguous block length **2** (AB) hai. *Yeh step kyun?* ABCBDABka koi 3-letter contiguous chunkBDCAB` mein contiguously nahi milta.
Answer: LCS = 4 (BCAB); Longest Common Substring = 2 (AB). Dekho Longest Common Substring .
Verify: substring ≤ subsequence hamesha (ek contiguous common block ek common subsequence bhi hai), aur 2 ≤ 4 ✅. Gap do recurrences ke beech "reset vs inherit" ka difference hai.
Recall Kya humne har cell hit ki?
C1 Ex.1 · C2 Ex.2 · C3 Ex.3 · C4 Ex.4 · C5 Ex.5 · C6 Ex.6 · C7 Ex.7 · C8 Ex.8 · C9 Ex.9. Recurrence ki har branch har degenerate condition mein exercise ki gayi.
Kisi bhi LCS length par sabse tight general bounds ::: 0 ≤ L ( m , n ) ≤ min ( m , n ) — C3 mein 0 hit kiya, C4/C5/C7 mein min hit kiya.
Kaunsa cell LCS aur substring ko diverge hote dikhata hai ::: C9 (Ex. 9): 4 vs 2.
ABCBDAB aur BDCAB ka LCS?length 4 (BCAB ya BDAB).
Kisi bhi string aur "" ka LCS? 0 — akela base-case border hi.
Disjoint alphabets wali do strings ka LCS? 0 — match branch kabhi fire nahi karta.
Ek string ka khud ke saath LCS (length k )? k — poori string; upper bound min ( m , n ) .
AAAA aur AA ka LCS?2 — bottleneck As ki shorter supply hai.
ABCBDAB aur BDCAB ka Longest Common Substring ?2 (AB); substring mismatch par 0 par reset hoti hai.
LCS length par general bounds? 0 ≤ L ( m , n ) ≤ min ( m , n ) .
Ties multiple LCS kyun dete hain lekin same length? equal up/left neighbours do optimal parents hain; dono length-optimal hain, alag witness strings.
Parent topic — woh recurrence jo yeh examples exercise karte hain.
Dynamic Programming — har example ke peeche table-filling paradigm.
Longest Common Substring — contiguous variant jo Ex. 9 mein contrast hua.
Edit Distance — same grid, alag cell rule; ek natural next stress test.
Longest Increasing Subsequence — LCS tak reduce hota hai; Ex. 8 ka token-LCS trick phir milta hai.
Diff Algorithm — Ex. 8 hi ek line-level diff hai.
Sequence Alignment — Ex. 8 ka DNA generalization.