From 3765fdd6198313c89ff41d664ed1fab23e5b7582 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Thu, 1 Feb 2024 20:19:59 -0800 Subject: [PATCH 01/66] Add Trie Problems --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6b9c46e..8f0756a 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,17 @@ This repository contains LeetCode resources which are useful during interview pr - [Coursera - Algorithms, Part 2](https://www.coursera.org/learn/algorithms-part2) ## Must-Do Problems (Topic Wise) - - Work in progress. Will publish soon. +### Tries + - [Implement Trie (Prefix Tree)](https://leetcode.com/problems/implement-trie-prefix-tree/description/) + - [Longest Common Prefix](https://leetcode.com/problems/longest-common-prefix/description/) + - [Search Suggestions System](https://leetcode.com/problems/search-suggestions-system/description/) + - [Longest Word in Dictionary](https://leetcode.com/problems/longest-word-in-dictionary/description/) + - [Top K Frequent Words](https://leetcode.com/problems/top-k-frequent-words/description/) + - [Design Add and Search Words Data Structure](https://leetcode.com/problems/design-add-and-search-words-data-structure/description/) + - [Implement Magic Dictionary](https://leetcode.com/problems/implement-magic-dictionary/description/) + - [Replace Words](https://leetcode.com/problems/replace-words/description/) + - [Word Search II](https://leetcode.com/problems/word-search-ii/description/) + - [Stream of Characters](https://leetcode.com/problems/stream-of-characters/description/) Your contributions are most welcome! From 35e7605cad3137f6e4bfd342417ee4ea9478452b Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Mon, 5 Feb 2024 19:40:38 -0800 Subject: [PATCH 02/66] Add tree problems --- README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/README.md b/README.md index 8f0756a..564a25a 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,32 @@ This repository contains LeetCode resources which are useful during interview pr - [Coursera - Algorithms, Part 2](https://www.coursera.org/learn/algorithms-part2) ## Must-Do Problems (Topic Wise) +### Trees + - [Invert Binary Tree](https://leetcode.com/problems/invert-binary-tree/description/) + - [Convert Sorted Array to Binary Search Tree](https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/description/) + - [Count Complete Tree Nodes](https://leetcode.com/problems/count-complete-tree-nodes/description/) + - [All Possible Full Binary Trees](https://leetcode.com/problems/all-possible-full-binary-trees/description/) + - [Delete Leaves With a Given Value](https://leetcode.com/problems/delete-leaves-with-a-given-value/description/) + - [Binary Search Tree Iterator](https://leetcode.com/problems/binary-search-tree-iterator/description/) + - [Longest Univalue Path](https://leetcode.com/problems/longest-univalue-path/description/) + - [Delete Nodes And Return Forest](https://leetcode.com/problems/delete-nodes-and-return-forest/description/) + - [Validate Binary Search Tree](https://leetcode.com/problems/validate-binary-search-tree/description/) + - [Construct Binary Tree from Inorder and Postorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/description/) + - [All Nodes Distance K in Binary Tree](https://leetcode.com/problems/all-nodes-distance-k-in-binary-tree/description/) + - [Maximum Difference Between Node and Ancestor](https://leetcode.com/problems/maximum-difference-between-node-and-ancestor/description/) + - [Find Duplicate Subtrees](https://leetcode.com/problems/find-duplicate-subtrees/description/) + - [Flatten Binary Tree to Linked List](https://leetcode.com/problems/flatten-binary-tree-to-linked-list/description/) + - [House Robber III](https://leetcode.com/problems/house-robber-iii/description/) + - [Step-By-Step Directions From a Binary Tree Node to Another](https://leetcode.com/problems/step-by-step-directions-from-a-binary-tree-node-to-another/description/) + - [Delete Node in a BST](https://leetcode.com/problems/delete-node-in-a-bst/description/) + - [Populating Next Right Pointers in Each Node II](https://leetcode.com/problems/populating-next-right-pointers-in-each-node-ii/description/) + - [Trim a Binary Search Tree](https://leetcode.com/problems/trim-a-binary-search-tree/description/) + - [Distribute Coins in Binary Tree](https://leetcode.com/problems/distribute-coins-in-binary-tree/description/) + - [Binary Search Tree to Greater Sum Tree](https://leetcode.com/problems/binary-search-tree-to-greater-sum-tree/description/) + - [Serialize and Deserialize Binary Tree](https://leetcode.com/problems/serialize-and-deserialize-binary-tree/description/) + - [Binary Tree Cameras](https://leetcode.com/problems/binary-tree-cameras/description/) + - [Binary Tree Maximum Path Sum](https://leetcode.com/problems/binary-tree-maximum-path-sum/description/) + - [Maximum Sum BST in Binary Tree](https://leetcode.com/problems/maximum-sum-bst-in-binary-tree/description/) ### Tries - [Implement Trie (Prefix Tree)](https://leetcode.com/problems/implement-trie-prefix-tree/description/) - [Longest Common Prefix](https://leetcode.com/problems/longest-common-prefix/description/) From dc7df9cbeb5b745397e539b61775a00bc5b0eaf5 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Mon, 5 Feb 2024 19:41:17 -0800 Subject: [PATCH 03/66] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 564a25a..f6da513 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ This repository contains LeetCode resources which are useful during interview pr - [Coursera - Algorithms, Part 2](https://www.coursera.org/learn/algorithms-part2) ## Must-Do Problems (Topic Wise) -### Trees +### Binary Trees - [Invert Binary Tree](https://leetcode.com/problems/invert-binary-tree/description/) - [Convert Sorted Array to Binary Search Tree](https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/description/) - [Count Complete Tree Nodes](https://leetcode.com/problems/count-complete-tree-nodes/description/) From b1fac69ab8a0b1a054b001cce90ae70c0b5aef85 Mon Sep 17 00:00:00 2001 From: Petris Rodrigo Fernandes Date: Fri, 16 Feb 2024 02:18:38 -0300 Subject: [PATCH 04/66] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f6da513..68d9959 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ This repository contains LeetCode resources which are useful during interview preparation. ## Fundamental Concepts -- [LinkedIn List](https://leetcode.com/discuss/study-guide/1800120/become-master-in-linked-list) +- [Linked List](https://leetcode.com/discuss/study-guide/1800120/become-master-in-linked-list) - [Queues](https://medium.com/basecs/to-queue-or-not-to-queue-2653bcde5b04) - [Stacks](https://medium.com/basecs/stacks-and-overflows-dbcf7854dc67) - [Hash Tables](https://medium.com/basecs/taking-hash-tables-off-the-shelf-139cbf4752f0) From b582f13446e1d069a3015ffbbee5befe23ed4614 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Sat, 24 Feb 2024 08:32:20 -0800 Subject: [PATCH 05/66] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 68d9959..2b583e7 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,9 @@ This repository contains LeetCode resources which are useful during interview pr - [Coursera - Algorithms, Part 2](https://www.coursera.org/learn/algorithms-part2) ## Must-Do Problems (Topic Wise) +### Linked List +### Stacks +### Queues ### Binary Trees - [Invert Binary Tree](https://leetcode.com/problems/invert-binary-tree/description/) - [Convert Sorted Array to Binary Search Tree](https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/description/) From be24a255cd9a0ce62e87a069b1f37fbd3d9727de Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Sun, 25 Feb 2024 15:42:08 -0800 Subject: [PATCH 06/66] add leetcode repo logo --- README.md | 7 ++++++- images/leetcode-repo-logo.png | Bin 0 -> 137039 bytes 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 images/leetcode-repo-logo.png diff --git a/README.md b/README.md index 2b583e7..2829742 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,9 @@ -# Awesome LeetCode Resources +

+ +

+

+ LinkedIn | YouTube | X | Newsletter +

This repository contains LeetCode resources which are useful during interview preparation. ## Fundamental Concepts diff --git a/images/leetcode-repo-logo.png b/images/leetcode-repo-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..ce6211c0a19738f4c0e51986222a90595bcb33d0 GIT binary patch literal 137039 zcmdRV^;aBQ6Yb!G26rbwa8HmSctUV@8#K7PdvFMz5G1&}2KNBL3GVKJ;QD&*z2AF( z!&_^9V6l2m_c>LyYwuk>5lRa0G0{lTKp+t22Wd$a5C|a?1cFxpBLn|g?Vs}jfv7Dit& zCa|okuP^KFdi{6$uNr|UHlo=7FP|gSsswfr4hb^Y{u9XI7vE@GtKi>gb>|F|sla`i zn}gKkdw-vlBZE@rCS8FE5y%A;tO3tI?FYgN?aUB}-EhU^+_Zw@RQc48 zGN0MVy3PYC8*;K?9A3}_Z5?q8I#(@iSs(U6(DS`w_dH)-Np}04<_;olN9r<%{nciF zT`4|RcugP%>cq%_B5#sF!-JrL{KP*Oa^X}U!vT(mDZA;)j&+>jtjL@URr;K1*w_JU zMqiK^`1$#XHv_7k5jR0iAbte?v^BW^gf;SLYwQdJ@@VZfJa&J~7&B3J}o%R3Tw@{9OG4@MyFZ{A!G|e76KM;q32~W(FbkXm{;Ea(^@#p!I<)bL zjQm3s0wIbqIj2C#&n{!~Pm3K1z<&v~2;RGYHZckpRc{k@mC3H0_k)`$II>k#$%fj) z*&u$o#@mBPgGvM2UJ#^V1Zrk{^)C9GU|8;RR2f#4_0p>thra9C0Lx1;JVGLg5T}X? z{~flZhf~`RTDRXj!h|WnS@q20aJ8=rPgxwMIk)6LLWi&Gzl3pA2UZZN6f}VDPkxXV z*5)x*s7WfKFs9p@QbY6kiQy4D=h($iAiysNq5g;f{rv^l8@mw z#ygCi+JMIx{-iMuQZc~0x2=n(^i?CGdmDm4ct+T6=$*#mU^p%8*lyeRjma+b72dJf8T0!(0rb>qea-Z| z46N*(UB`dZ&72&fB(ySg8D^V)HYaafd@5>32q91?L%H8Q-E&w3Im)S{8EjphaJ2^ za;HG2D#p^pY1gr@76$o{{b*;i51}dDWQGVKbhsu1WxMIQ@mZ^4vxne~jbQWWFad{+ z_NPgx`%r#k-$|IeNaf^XF9E;lT4(MPtQ@Di44J^J zXH@hmRtA6cQCkV7MruTqO+vg#F1)3Aod&Mi$6vOOzh3+3j9?P2@RwAp@%Jm|^h?Cv zWCWu^Q?(tyCwe?@Vh2Z5!R{jZZ*i2&PgW5446oZgDgvF`mlcv2Ht#dhJvPC7?SE__ z>)e^Unat3G(`b|VbF6p??sEok5ViPsW(zSi-RVtQYSyo~-%j0=I`m{}yq3^#M080t zI!~)SEuzSh?Ap0+Hj69~UAawVc?=E2_O*sivwi*byX)d?peBhV-JKZb{Z#mxqCKw0 z+3xYE%1FY<-on%Euk?s^kK`VlTn7;zfVOR!H+5aoY5_VnYvFJlk$3 zGwgRw7DbQN#qORL9D1qNH&H4Izl0lL)Ub1)Y5+2QRZ1CZHlqBoE2{X9^p*f2Nz7^9 zgcgH{NlvuMx9S^KtoP~R_brl^hss$|PJM;DiC|h?#$bQ4cY$gIzpI9<(jINlnhce( z1XJYqu~fF4DO86ElztNjs0C5DKNT+oX1!H^i7Zz@(qg+e!O#0m?2St=a~E?74J$e; zAAc{NZ|TJRli+GI6jP(El~VY)P3FnU05p!3J>~x56MS|m)bRnK^Jf*A1xEU;Dq=_s zPfauNE^$l3Wh9dR$|vx(VW6qN8~e{@zKTEHUh5cy)v#{19^)b6z~8Qr%AZzM4>=fi zB4YriUVviB4jjKDaSR&@bE(#@x(kPk!MKSf3CTN~H<+HvZX2-pkyPUU^$DjSj88=G6_#cVfp%ewQ>7 z$z<61!OW8pUnwi-GaGf5ie7E!D`;l&Lm!J}vuSr(yx0Btptm2_DV%vnrTDZI^(I0q zN-IKGk1VZ?(7QqJgi!D`w+dzE2GNZl)9!8y{%Y;#Mia(~8jWfn@#@0lDTX)+`h_ON++jqJ^W(pL!wBrnz%Rf7f1X5M zd$g!5x!|(T{PiiMhFrBLq>6F3tb%AK%OB%xhYtP=mKM2j(W-HV?%DLX(quU`4w4E4 zy+*c!|VG-I?-JHM+|-BQ?1x?AdSecDR|BNr^$|B0B&%c8*1ujnmV5O-{WOH6JhE# z&N_@BwNXbnjuGQGfrE$>$G@8L(n7vwIEph!MbnY9d|ZE|PPYJ?*}Bs#U0Djm(vApf?0#Ru(J{b5J8A(u@e(V!Dw3Qnw!sBYNJyp>IlAv>9p61a~BX zWpVBu**<)Ota&~m=u4nsmi-bT0lAB92wV{pF zX;4}Fgn-;q@gMW9E~G|mqz+lzTY|>8K>L~VsHMVbJfaKBJt`uEDjH1v82{UfFkC;| zMhgw;`O zW9VHuaD=4tPW5cqu#L1V$V3%lHRlZ>2a8EZF~mv$Bc1aO=&qzwP> zQh?j4c-*u9`v5(3@@ZUom0#;Ttl}dryjjaV&=kxS|JxgJEx+4KDBRL_K1fvOAXTV? z5+m+8OA^N9OhZdtAZl|gBU9$TN8jrq5dgPlWVCLvm{buG+JwO!fXa{S@xjc&JDL$O z93%@z9c2+1zd=HIOI}2%c-dUVmRTkfY=l7y%4zTiZf7jlMcvtzEhd=|6p51o{?1>+ zM*CK-yqemU=BRr&cRhmHE#WF)YFN7*jAqD7yHr!A;^20smFIpwJU%%}7g8`%rGhp8 zH4vSXK`uJBpPvB$8^LCMTUT>k$y7l*{^R459wytE{2`pRft z7u{{4+|HfUM4tHy$smeLH8y_#o!b&R*_*w;naA`jkgschLn%xd0;j1Fr-)g$S$Yza zk)V#ik;AJ%dgye$Fjo4HLJrjfkgA$?8rh=2-l0M8fGb)%a1 zOdM`~C?OA0O>vQ>hUD{|dk$#`t}{7p4<*_q@eb2N%*dJ7=(JVDayq$_TFL2H z`I{#q@paHVERtI>xcLj$f**nsE#7=pW_|_Pdw6AOdie5H6$ac{>uEh_knv#aQl8}N zM-l2z5z*Y7^sE$nTGiiHSvgJUGx6dle!h&KPv1m$uDwWolU??7j<);e`aOJSi2mze zY`G40VGh^pM?dyunDoKO4AhAHY2#_9dQJPNjYmPKgF&3&>jh3m`K}{}^d?4kuM1X{d=4Z-16{!+mrUCaGnNhGNU{Tei4f z>c3du`t{9vj2F(q0WOCN%zm02UAQ%n#z39nj2I4?ZP%&sQQ&uP7-=w?yS*J+tHWVW z8_&*Q331X-hNL;Q5v!gD)K=;V6*Rk=V+5ho@D`ws`fg8!I0+|}kHmd-V4R<(KJtD! zxm#+6{RPCzm|0fpjG^JRDiB`0A83h9+ZRwtZQzWi5==P66CPv3Qp}wvY)9S40}-oe zh)klji7GVjC6QS2b0p;W$qzbh}98mA82Ce_3yD939qHVgVY&7&hb%Hm2TRi^wkwrNjmjS*zBZPYh z+h%!~70EdiU+O{`N%VU9BJ>PQ895HesQ2ixP>6QlGZ=!r>$9Gs+?1>uO8CCS5eY-v zOWo+tZym5Xx}~^uPH%A(v+2*)rPlQGiR*8hI7dk>L)Hv=4#rt5h>5xVGk34{`Qb5l zjpW$kSaTCmQZ214X(n;fctstUlA1ihbKSThEd0&0^UH$bVbZJ41wXx0+Zp_FdMhG9 zCPBdx!HVE>Fn4Trk%3VC+X~T576fX&E>w_apEDDGvukp9X(DA4{t*%{n=d859^9nx zdo<d6-zEyg8_hZ}~fu&#m_# zmKtbz;V|J-w!ulG?c)?(qfX~_o4RsfeNin!BlN8EG|PctB!|N26Z_q!ail31p%91%8UyMiR0^ z11f_8zW8PKfaDM^Ef%%q&kL0RcErygIyn)`(j5E`x!_*HMWOFG!o6IhRD21dW6yRD zL<9w+=QRZ=(*%fhZn-s^=uxZFU~j@BC_pd(qKUYn4)5zLI)b~0fZd3=!4#Nd6-cA% znR5jqm{}pRac^vknSHgczrXCq*UHnTOVi`-`MRjcwcEX5Q{y+-2F2)Ebps^o?X}6& zLrDK3JcbM|cZiIzlAx2>+rQqcOaa7E%Ej}RmFDUiJosR4^5EyJ7p3`)_A>$@f=PaS zmoF#OUsC#v6+oWcTpb8OSKMNx#p?ZI=lj=UZy0)H9Oq=qC42UJO{3>)kW3nkXb|xb zmYv}mNJ*mtgC%AKcw-iWqDOPAmk4Qjv1kxof)Un63CH*Vq$?Cl-GtfvJVu#KmeeJQ|!1)r1KyyuV5~qc3 zI$b8Mu}rQu?yDXVGHY7Rh@D`;kw*%cHZ;j`>_`zJu)m;-2#N$?n+w7bhlU3T@l2- zlGvFtZ2aY4Oa|tg7gnws78kqN!%VZsr!uHB=c^X z8e?%=E!IBvOQP}F7DHOH>GvNLb7yZmqkD4p!*><)@L#NcBGFWn;#z!tllF%S&o7^+ zu;%MM@i0M05|znn=q{AN`rduv7w@xxPm`U~R{FrT*02E%=NyIh`D3oxExI6~iqVMY zoVVilMmKfpv(y=?6cz;rGP=}!y_?}f4(~M1=eJHae?zwg-;$$+M2d9S+$+c8AaXsW zeX6^Lwzx;9hyGlGR#9{!@}m%$HIf}o{KL(1VwvulXYz-nL7+E*3xt1CEdo2-vO1MI zgg?|(A%?`OKvWe`Wfy z#rn*Jq5oCd1v!bJ7;08JzH14CR8QGy+%uj8zPvc5?O7|74v(wqq8@<8V>Ry?raAIwA;FQ zPxC1^6fo^-Z;=be*DP(s?7q+81fr<;I;zmdHQ7#1IXkM{sfFij`LW$FaVIa9-F{Ue zV>;?uBj|15MU(1&iUwMcUhNhBRj(ipz=3-mL|4bN){I+SWglqbC zK~~V=A50d96d~+Gdsc^e!~7^iB2ojCm`s@y5dymYm6}q5kr&9XFyNYo-*j=WS6G^v zfIP4|6`?FY2#+YU^-O4TvGdgM{vq1Y?&mSZ3`23eb#p8J^;B+k;<-MAibDD{N85Er zKSRwq!$@+wBOwJaep16XY|TKRNRp`miE^rQ#Wlq^DQj>ma;bbInu~gUbetrnsi^vC zfiC56{pTCX+UWrq%w`nWUJ#X8d${l|dyTZsL)p~%11=`}4xBc%uYy0nTljG*3o3D# zyTISc{x~m$810A!o+2Ev_{7cJ;?17t5%!*96V>#}OWph(8~jdQkG$fi#IYQicT8KE zNE01d>FVhPS?upyXr?Y$rgQA2Gl>iuZUoAEm8bquJ;rJqbI4BUbhoC-#&JZ&t=sZ% zY;GJniGvF)jiS4F<*C^$_-Ky3(6uz0>qP;NzNt222qV6)76dCln{hu)-46>JKQA`O zzQ+?Px|5*Qr^?@*bAz7Y)}D}x@_Xd7`a^PgWy%Bi_*tG*rINQN0g98>#qckw5=l%5Prc?im(oaZ_qpoF2=lNWu z9Z(g|;f5JkifS#4Feo))6w=eSV9MbbC&o1gVH6EzTn{IPdujhK!q>dKAsoK@vU{he zspnNlGgaBCqF19a*clR?)gD9jg%Q#~0aB=+sWlSBM?#rK9_9EWEyDVyOlEAXtQKbG z=bLd>0`r^8GR1T|aEad+{P9Z9aZ{W%tD#k}lV;TC6rwQ`Tgr%{9f#l3}X{#%W|_ zG1t}r{@BeJ;NNu|ZQgwo(1b^cC%%{A{EJuqn{$QZDBo}mFYuuWS+Y>z-^}2lk4`Tr z7Jxc5jPS~vYZI~#8;@pj%Hxf4X{8`F*R!IFf9ez&ZN3lueBb<5Yx^buw@X}}U5qih zQ_U*MpXt=Kc#>59*q%4pj8%zUF;)DPy7oI=!O!B!N!fqaZFZ5oKrz~BJk_~sy$}9Y zO%;a~wD~8c{!f2YdR3DE6A>8;V_WE$uac`qzHD-OB(%`5r=P!NYe94l5qY#n{d8 z##eSNWiAv$vsPO28Q3;tPIiiO9R0g<`097X_p+y*jQ1-XTM$0`=lUzd>sJHfOLIz4 z#OgxMFALWnnTIn2?#fgAmHlP6Wv1$)%SFnj&mI=V@#~#ff>q%DvJ}rJ{hpYfP(|x* zx!dt-=!t!?ogp#BdvS5mq#og zNoYRtxMWhzzuXMc_{AJ&6p(HgJFeVMa^d3D9gk44 zv%k$X8rk%9H4|hLL}RHg1N=U1Cd$wpB;E`=e@- zBh_h+d;K%2eqORiILXnMoogHkKqrS%EwnsY_w?kaAe6>|T4uI3ZVMT~=uno-@cPdi z+8`L#y#ClxTK=-!BV}YMi;qNepMspcj);I;p7>qfqJUKgGSpBecRP4T%O`Yc43|+( z&`g+}N%A8mUZw;SWB;pWe1Q%rfs!>fD)Tl z8K5f&(C%)Z!}I!das1kp4+ZpBg+593S!x(|4ici zkyO?Zq*b4&$A=bxKlW!3xj-Q@H%wEUIWszSc}(xEPl{PgMvpLDr*As9nTT!%RO(nC zqcn*yaqOeCd($Y>POD9l_#D&g7@tTuv1sI>Gf^Z>s9s>IMca5mG+h}*8Z)LqfV}2B%+P75Cf1U^G`)X&o~OL zVMB`9cAQ+aEZV+2g?w}$w}nZQAY7ywZ)!RARoxwaPv!+=+oXwALu^0x4gE)6(OK^? zhR%(24G#6~&m`gk-7+ju=(-8pgq=;o&EvzBN!-DX2tXrK*0-IZOiuHbn;K$2j^Frz zZ4zF+g376pV=a&IW_kzw9fGI@5r7aXW@@|^(E6ZnyUodL2gd|OUm2i6Y1Qk7^rLPS zkWkFbq|hwy@eS5PLU~GUBkpz8@HKVE?EkZ)=J4XrZMoAg#;m>y^p&f&Y_dEv3cnpPm(On6!I-{9IC z_kdUtWqq;W0~J%b66(7jGS97u1} zY8cHPh^%^agH63-Ur&zFP(kmbrQr4d+ekM+7s6-P22T)Ckr)#EJp^p18SW^}bG{T`+QB zr<-!<%+)Uq2k=m8Fs(^+;dc)&Bok+1*32dN&#}l56M`5=77&1liNhOAaml99g?fm* zL;tNqL=&?3HWYi@l_EGec&^Ej4mSdk*ks&wS)HH6qyk*%Dt5>>EpTaQ~@fyFOk^xCRw3}(_w(Z-RSOOU#r1} zq``JE%zecZB~IjtUqSd%?O}tc17zf0RJ1AbPv#PLAj+|Cl?m-p5A9o7?}ECZ7?*;C zS*0KNnF7|NXd|di5r$v)i3e8A=mPlKI5W_3glgK9*a>)R>Ge8Sp)Rp8oktiZSsC9&y*K(&%{_!jJurSZbFfa ze|7XCl;Q!8wyVAJb#>YM@6>D%TK})3Lc>I2(I7FI-6=(p7+H=sd;$W3abC<6vt~m1 zDS&l|s;c7Iwcnbz-W`+zA&QasH#&3!PRs^0&C>Qg;}}>1k&HmcMqzaIoa~b>1kN zhA=AU#}6`&_M7k4eEC=Mu*29yzg(ZK z9VH$+NB=2Mkjn50M~q_jr$BhcVbkSrUB~Cg>)h&UoC3=*t3s!5V|`IX-oLN^rRF|3 z)TbqpjKiO_`oD{Uvl}Z%=8xuKob}m>`Cx5lGWslO%Om7`Zb>p3X2#GNUgHyz)B&`6Ro|p)fWp74AKtM=fOL2-w{`K|E=HvCMJ6q9ov-m%o zN4fmLVNtKHXUhk|2*=v|%peYu0G34t%&)Ha=8Q;YOlt*cOGqKG)&+1lEg<}0@>xVgIKw6!f`=Dt?=_f&y>zV#IEv3ie1w8MF!fNu2h zQ%C|WAhbv^(i73mbl!TR%4f1lcgRarH1tYuQqA7>;wi3;`9JY|`SL|P?(m|p(2^8@ zmJ|*{g94R*P>)MPiGk>|SOb@|4kVq69Ip%%-1gGppA0Y>bg9Rz@kjv;EEMnWufmOQ ziT6s=vL&eOFV$J%v3EQ;?X~!0ReT)0gv?eNzUU|Z7tlXBM%Q^T&qeOKycZ=LEvq$? z0u`@t?^as?c+5M^l_~bc0JXAE*dk#t*JF}c(Kt^@-v-Wmd6cE12_D#aQAr82l^(+` zIZ$;l6j3Qo66(VKXLPiQ^1LNZLO3Qcxfq{o>Rg6sVgZ?!ZCjH9njEj1=AzAjth+i1 zf{B80d%f6W?ZRiiPsDZ)>M)bHDiCJ-q~VD@(QGK{PvsvH|$)4-G7?RX*717d)?9?ylWKRdCy z8s~cWyZJVL?E|(q;koa3FTO$4{=6vR-K!eUty@v-&D64r2HdDxsAD~SU+t^t2W4<* zwzjQ$-BCE&U?iMeqA$YA3tM2k$duLVklivz8Wt#Y(uCl=J1S*jLdQDHY$;?K4c(v2 zub`E|rVH$-&7Y2*b#J^|-pG(}Zg-E6gx77b5tEn4)X~*lwpguUbr)HE!!aV9I52Q{ z$@r;SG}-%Wky_X3Plnr0mj{$CV_~&&2X`G56ckM-Er*=;E0BxpYl&G`xin6=sRH?) zP$Gj*EiHmtDcc4@{$HfcYpswBI4?SNaUurd6$*D|%=|oCO-5U1&q54tA=_ zHc_d|QRZp`a1&q^hCCSqDGKD-?RXV2qY8?zXoxm@l?Boh%kZ*|aH3mGvvE!_TTktH zpm#f(3k(Yj`>ZPziv4L|Q>)RAVqsyS>iOyZ2fP)RWyzqU=|Nd@jh|l*uhnu5Y8SJZ zYsBX`5n-B;LnN9hjYA@-PWG4n)T-5JL$bn(21LanNL=JYanFt9su_yS_~M`HAd^8`t2mN$(v z)#ayZ+!k;onUq%v&KrZy<5QQnnASAiA_f8E#hNe0k1+XJ$fe7aO2J?YZ}${{%MojreEf!z}>0a;}#b-3h?+~16^>Dlz`b3ZZm>Bi5Y`LK07HQ zJN`s6NjSz@Bpkm@>Mx015>;McIoImRQ_*&{Abse1N09HcE8Uk{ScqcZc1alf_HHj| zvB?l8DYEnav?Fde%b(J|p%-y?=SA)| z2j$;MGjX_C4@Z!WOJtF}#ZZ}6GplWEB(iV6Wq573^of8)BO3@>iWyCUw2^}Ywm4W# zT|K9y1no-!Krf)@TR&kTtDZIRh8|28&skTt=}CbG?PHh`{e`#q5-#T&Y{?9~kNH|3 zuNJkMo#uR=^p3M^7oR1^Ruo&%1F(`*PIfR(N` z#**_q9XWK%_mgJN>)}-WJY$gHloY}|m0}F*Tx@tuOw74z6BPFL8)L}d5uT49KmLKt z0wmH*uf`PB{MVOI&%Zm+;S@GvV&cJ95@u%fq-11{z#*9|)LHTaElXKh8D|d1^a}$< zkHeH=T8^PT80U5#1aw`M$ye<%qAGg$;tdjRXv=J81q6-h2j>Kcb28mTxkUnFhrm$e^msZRyG{- zX62KvT{Du9+tHsSd2ryO-49I0Ob=SS=50c`Oo%|8N;dO16((JQ+fp#tQ;H-$}?TkjPaDJiG#oy)_4 zW=FT*{V|c{XF@(I_4EW8O@Dt81FwC02%v*Jj_YTuTn{xcu&`RT&wp5#5E9f!1JvWA zrDYeR$n6Jm@1tt|^$6^Oh zzjt=7EiAt|OhE4^wz9T{13f-I!f0)^=}%n9)6FIjF!81|(-5kUx*(D=V>>WUtqX3p2af8kd5m6ofD}^<4>oM-0HAFIPj;Q4)%` z%`PoP9}~VNe|oy^Fj?;o1!^L^)b#GzROg^p(EG~f_)6ckrcYyo0@$1fmf~^8coKs3Bu+j-#--51)gUhrt8hi>TPqqE zZ1OL#K&x@f=TGQmE$dOVTt?OKh5Cdks2YnHhkZgu!akw4xA^V4$jGU9j&b_%P%+U zFZ@3Na7}c1c}XJMIcQM~z(v->7US8H^H@%OJzu4i3V~IAmHVu|`+ChVd$8q~qVn=z z{BIJZvnwlKh}=!YISjKkHmyUG^(;MG&icvD{$@Rs1HmXNE4!FRs7emW%%qe{=SF%V z^1z8Dbi_HmgwEdi&3z@E=7#8VfmaOcaQEu-lRGS@VEh5-cW_g@%Unrf74yvJnLy

bIJ-lD-|0Xa|*l&O2Kt|io?pMerxi{=>>m6DPgJ!E2Y6BZUudu>blbT`}4 zQjr-3T}#$9=u-4M$1BsSh6fIn6N7I2cs|ajz}w49Nmn=O$7wqmz~Cgf(RLG)18ni25Sn>x{oIsmWDct^Y0g3t2Zp! z`|wMjhfdN#l!0uk7HQCkrE$=_10dLuDQ1`Ci!tIo4W^-Q%Mg`csbqhanT@3of*~9o zVeRTZG*qrLGvUNJ>z=%%v@}@Hye5+@s;|oPuer@~OZ_W2d9(_^Q(-)5yEd5hRf-+1 zWgULp%rL2JyXv0ImpxlteR|z<$pN1E4Ad^HVd%Ndn{i?wxVpNYa9wgx#^vVcBQ>sg zv77+s+8PUPGcyaz#M07H_0pEt0O2Io zjI-R7B)~CX{1N(icWD=HoFrIGL0MqgGP_6he1oDOxc@T4v7aPO$ekSs`?595fB^j9 z$HW6Fqt(Q)Fl630Z*psE@!XePiC~v5c^#HlY?OEjhcNx{;((z)kheSEdOzrV*gWI^ zU8WrjkVnq`C9F()pG`84>t%QSs5;9pIpzx~L#`4M2r9++qax2fkjINDfYi@bK@r;j zemh+&s~v@%yRxQcIKXwT-)>t|S&>chV!}vWvoqr;;a3ASDUXFaK;MDsI4T0pzke&~aAl ziA%2oObNbYoBp_BE2NDPu^f{xKO$6AC!$6JUJrE`tc3Dw>W+s0N&((hR%U-dqcp*o z)pN%DU7>#%dyE12l*HuZy*c5Okzegvm`rT6+PQ&}A01U-)o+<5F#X=(X-RT)bkqxY zP_bXWkj7!t9~S<8lPr^ylLHs`_U_g1a$OYtS!W#&b#zmEdyb0Ma~X$GoT$DU=7kz| zz+g%faApt`5?VgQ`;9B$exm2%;zCUsx2v|NT8s~DsoLYr7y>Xk%Ikf-ec8}=v#u`g z?wj4{9KGolnGxH=sj%z>nw}l`v+qyM@a#>M+f=(^d3kv)fHIBpZ(`^HU25<6I20Jd zb+QkCdC{TN?)T`G;WWh51pHJ;SyeT7VL|8m#(_pi0wA-13~a>^6Q(LTXA^?Fwq4lL z$s}ag+hdlkc|=|=^cnO9YD7mzXMBD>0%r5A-j2GDPfV<@#Jw6S^x=*g+`2_loYMO?*48~2`%{iU$2H#Uj{&HLV`c4_8CPxwH16ko z24DmF`U;bhlKz>Luj1(xq>+;mbxhdDaP!^xe% z3a)R+l|zNxiD(kFf>)2=O8Ymx4FF(U1eW9upnaDC)H)7w{)sGQI1)Y&sYTP!moKS?c`Et0)(kUlQuwOv z4bV@zU}-!n)!fpuklULiQ=~SP@C^aTnxe|e0paVVV8Cys0NCKCm*aPA*Sd{%efx!3 zu~JclInB+Ua|8+zR)NdS&K4j0%fR9F9Uaq7bk9D zVtP6R5M9`X-`q$W?3PJC+$J5D0v_epH}-DHl|F;+T{Pk3L4c~$1I)~(s|9QQzLvE4 z`fXpJo%D}>6FLi~dH|8VwsBzeWA4K^=Z^D$#OCDCJlqV3ymNPV|EL&F9h5l(s1Z!Y zEFbQj(Qi>ZJLUj#VlCF{7#hZDv4#PZfpGVmd!|rzqSXibPeq6>cY{CGCV#*0A6~Ad znd0~erho!=7{95BYN{$~cRMha(?3%i_&Xkz@rthmyO+3UZH>C3{q8_I=$qP-+v!RS zhyU#`tZ#yh05v4dkeCoc)lUp~O&iSLxgU!z_xJW3mT`KtHuLCB&o=rKLOkV4;lAXEQlOX>+tAPeqyx9%r~rdpS^$jg0-T@|IBQ`8xLZNj z5NxeBFFs^sBvm{c@KUulkxF3nk+CZM_jHxo$9eN@mvt2PjqZE!0rf zVR3zZ3Lr36vn_7DIPWEOUWy} z_X2qSpMEm?rr)ESU>YTD?FgW88ZWoF3Jlbgq|73r6B^A{=mV@XXIY+Y*lFN4R9P^U zO*hQ{zR|x25HsU*bNsZCUq)B}B(AR~P!xIOeY)>>7Mjj`ZN(T_ad-nz$move$5Wt_ z3~9BPy!@lv(ye2^odqRsS`Q<003;MGVAGeBlpI}47g&E`0PNr@qb_(opR+!IF`n0r z>1lZP69Xb~>FgVHEhD$00t?8TepnFt`}@BytJUJn91EbG3zU_X_5f~o9KieWdD~~7 z%ii7})!vM{w+90SGD|16^G2`8%nHy>%kHZ&KTcXo*XT3A@S^dvVg(yaW$VC9K`bET z6do|t$bq5fWg`{a?gY0|#S1zvKjmfI{QAQe{x=A~Y(bpmn+o;G{(jf(ZdP2eY9Vd9 z96Sh1aF4pzxO!YXB}2)yCkzv?eXP6KEkR4#lyu?g#>RGrh6& z_4QB6QlUx%cjel(3~Cf4CNTbr8zH%ODZ(e;Gd_+T3ptl|ANe98ubu-ViK9ZN5SzsY zOh5_b=$8#gWPo?#{2%CmI{U0?q{-F`I5sz%RL^^(rg|f3Eh>G9W<{l?!``tv<};JG z&rhq*&K4yU3bMQ=7{zL600r`RI2&+WcAah3Q1pZ>dIl^fU~iK#EN%ln$&!mq`CyS{ zva{azBPDBl`+?lJx1{s9MOdK#T?5>#P9!3|0NA0b2&s&f=rjQBc*&s$6A=G#yzN=k z4~Q}HVI>~izD)xjDlh&SQ)2F0eO=rTz_3+rZ<;}U4gRk6P@x2vk|m`T;_mK^Lg>cC zdEO^tC=?+u?Oef!4T4z*vwd9AMlact0bYL7@q91Rm=Q`nKov^hm)AWBOp>0So;oSL zJ=^kT%%2`^6Oi8S_kRV5$hB@Ah(e4mLEi?*YvS@X1;I z%5(w!cAIWN^V%}c`#=K^3~ivc_)lB^0=+#DD1o4)Q77S2!1eF|)Gil5 zQX0##CDokdj`)DtFYxmSI2anZ))Nd?c*sOq%=3u>!{Q`_nGO17+$`TKZJ@P>5Sr)J zq)5MX*iP0o2L9(bz{cJ0&u zfV(2G%SO-*1lMM%iL10vwci$C1iJQZ1YRR%N&-L{Z;#@Ws8KdA0~Q`YP4V`)zm~I4 z@;L$KmtETGB<<-V%sc^<9Wua;5|R}7%Bl0^3{-(JuF3s(7b|Jm3v`awfaM?VyDl9m z>(N{=vjQ-Da@cy$eO%|`fg8KHxe5jpF!K!@t>d=H3In(F- zLt{Cvq*@5JUz9~bsqHOWrl00wf@z{u;XebnfQDB<=mu6%CTb@!cW# zHVyWxvFSV(Ei!8O`7k#z>wan1;cmb1hfLBzw`e_Lmregtj$EH0h_(in26C89m1#vJ-))rUu=Fu-Q4hO)f8 z{N_)%NHkC?_$cHKAmF5J6I` zn$ys{C-W&yz-Q)ND_xYe(dqKhhKv`ta=-y>!2Bt|RkOTq9^5V{(`kdLKgi8m@JBnl z*d?)-!vGd=^7Dg1B;Ul&wSjjKfwHO?kWR9PS>Ukajg7?utex18jHq0%l?fDgeb+VN z;gqkmZRvUYYr!xlQLvOPet(w@auzlL{{e_ClalvD{^dqv$0Hk{Hi$lCD=!bghHUQN z@ru_5KXAT%I*WU+@zJ=N80H*bUAY|rO4f5A;dZ!>SOO4F&dxkQ9}`D!t(kp0IHQrt z5n2xvO24xK{+8?M!9h2Wmk!g)?>$4z`9%7O0X^^uaKOeBi9ZY2? zC)u6tc;dUezgIRiq?(`nCGg(Df)Pf7ZpZv7VVMT=OWj9Gv4P)J_`>FtfW8O;6pRVr zRRE3rq-ly%rjER}*=1kF=g5TWZ<8}hGVuN)pm%=A7|q>XTwbp4<;L|3>}CXW_?<<~ zS!DSFydeGB=Vy)CaFx{zGca-RI!ToC2fSL<0=cd(6sn`@(YwRaw_h8V-N=BqHi+g) z+5V~vQ2@$RZpx+dM}Z|EOe+ZZBF~wI-KXT=tk+E`I15SDEECl~CX;I0^#Jw}C#YX* z!o+*VCBK_Vh#p48fMJIz_dc@)w32L>{BX9?-G6sT*KYfVaep*P0)w^cm}0)l-r-?S zZv-Bf>wy}~4uw4{geUwIa1~iJD|&%PskWKtu4`<}t*M!G)g04&UtdBGM1x@L5Nvv`!sC0TsxlZ?IoczCH$sHlP=bwuh1{?kmU- z36PupR$!hjtk?lrkwbtD0=|t5ii>9qeJ4K!Gf`Nzs{Rj6*By^_7xs~nkz^-3GBYAs z*)l4d>@6c?C3~hsnI&Y;Y%;R9@Q|62kyZALBJ;gY@B4l}{qa0~bi42KJLfvz>pQL+ z1GqLEPi954Dqto7xpt^4(ETj)`+&u}L`z7?jfkq{o#Z$xq(6Y0#W1a)wB8?@oAV$V zRCaBS)D~NqnqusD(7rQt!RM*pmO%=KXa5XnP?WsJuhvSM=t0CMcEEW@IR%|{sPImB~s*eZRy}8sNd#uU`W*jur||%pj<2 z(EBP#a%{~(-TiAGl0A4Q^!^b8hKiy01BC}ta__8 zHu-L_oiyA0lKQqMoxt}u92pPhx*qNrV$CvQyiV~jKk!lP8i`}4Y%(x{s&;eCFc`M0 z{`po$ia_5#-|!@lzV(YcXjcB<`^@M0%Mw=WMM|_bfn~QPDcXYFY^m!?x9-tp&wihn zp!v26Wg1Z-Wo{o-cV@j1l=Op>Eq{h?^Q&+B;8W9j%m!A2>f{VSudXxbA@iG7S8@8z#-q(} zsJ;q1=e71{eSQuLUYPv!_-W_U=l8)b{f{RF5Wo*~E;OP0wLe|<;}+(HmxMtk8U)NW zbG&$K)4mY=+;LVdAGr;kT5zhjTM5fKZSvFlsM~;0nywVhtkr=F8Lo2OxDdp=&m4|^ za#}Cz%&4p!NhV=`t850hp9d%tsP~6~2Q_rGW+|GV*UQ?6rgb=nq~ng@!9Q`Bl2I@6 zgw>)lbiypI+Z3IGPhLGA#zjEmU*vws601Z+L}UuM1BnR%E5o^&a4IlLXZ()l6eJHX z0o(gaQJ}{z@p*AE&ln-oWO;65C#r-^$3JJBq zYc+S9ycj|UvHyL@H{2n9x=mCVW8C0r+Wd+Gq=bvw!Ezu#Rx^_SD8FX0BtDG>aoGPFM zM;4?N$~KDrCk$B3$>wgl{wENkJ+Wn9YRMS`rPREWsvZ?L4duHosCa^(F{BT%4h02V z6$2bbHek+HwE$$7A{e-beG63r@XyeD+2_^^H8eED->@Q}_dj-CZ#p|ImSLgbyV*#a zijRT3A;=^K>)`MF&Nx)GPji&*eJRi66zr{y%Oy!AU+|gKjEpuohho`O-HkL(EXc~= zKG1ImBb7NKv^-Yxa!YN8uYo6m9x4{{>^YC>S^u=}S@kukbHDzNKzFQD|F;d%9r&-) zo3PEbYKQFxygIsG03f_xh!6v?GItTS8;Nbvm(^7}R3G7d#|t}~Kkq4?($UrqarY%Q zP+ieCP*)EW+o~snlTVD124y78T2ng_nD}i#f#;DW#qU>aYBi<(x4-GOG^f8!&M1(u zba;3uV&2fv!j{U~{+x>-w zr++w}NdbwA#4~Q-H())}CrXoitU=NrZ}7ea4JR``zs9ook0@E@8V=~Ye|8eBoGrc}Vr7^&1qTM$fq5X|KcjBC$ly~(dV0(CyX1uK zK>a~e+Lgo;_KQaQ!2<<-Wd#+R-|&<3YbIx+j6H6_FAL)0pa36QartRoRA8ZABPZod(FW}|W=xBePLWfaj zcKWAKq5#Y~2Qz0UGXq=v3C4i3B1Bi&5s3~?wR6Zi8*Hbo72nd>u$Sm{);5R+Fk1J1a+I)=#$|Sd+6NZzcI3K#I-SvYu)k+ zY;;Wnt^9-?{ot8vDC(ji{l)8+Y4UZ3$JYFr`v@c>log*U4g z&=r{u{tOTfQoNo^bJio!ry%j`QY6a~_YmW#x}IQGy0CW-{*G-I92$V8#n|6H7Ha|{a! zMPqG$jZQg|e|A2nw75nfPf+7BHCs^97={>P*lN+(ge#4|x6V$tgnz!#Y>vO}on=N{ zOpJe(&f1fiPPSf-Su?x4qG23v{BLX9MwSTc1+@XukvHXIuAI zR^>9t;s50wKa(f0Lw>nWjyO>wpG!ajHfj>EKZ)&TL6?)N@2ciy$NyZ8_J&pK${X)E zPeRq*-OlFq?KTR-Q6$9wl~STtj{CsS8AnBYN6ygo%gtpV#lT!3R##kTF#d=IXT`No zq*LIO@5A+Op<-Jaq;d6g_xz1o`j1r;EO0zYKEJvTpjnBid^A@3Tk|dP*@*^)SYGLW zGpmKg(hdp^3t$He&$9nuyIdOqWq8_QKfm<{Z>FT-`F{pikYUnaxC6KVdLQ{}V2|ic zYC*G;^;D|(@Hg~^&F3z*L;D;dODw{2bq4xV#WRNO~G1W5W zwp_Fehq+N8Ka7O4-Ue43(5NzZ?mTadxITTQPHnMS`+-sRSs$NDx-BslrK|Yllf?Jc zk4IJ1oAavvoYyhzy12luxOOzrlwY*WUb@gN91_GzV2tcMU;=1a+7;mpV^Rvl;`Tk< zYoT~x7zn!_3zm2L=tS6Kn-Q5jL3#D{2PIJ0X%>T+Ryg3-FBgT)3+efsz;O`IhQ^XQ zdJoDgDk~2u90$LoxO6CX{kBwzy3_*=jUbTax}r6ySH(FLr=SIaRkm|_!11N(<3|k! z#`AdD1Q9ehm8mY8W2p3v0uHmPi+{tSgg&6LG5smf49iQ>9B)~qX8g~5p->TlkW2$K zN7S1)&w6|B$u_V3C}(?@S6fSC@%fdsvvXMyMpE%Ul$$nSC!PV8m~^G=@QX=EcnSRE z@y28SHrM{!FMyRX|Fiy$otqomiADbAS6a1#U82RWLp8&*&tpZ}S-PO%aRTFwIRJ&Y z41w{R!)2IhrKKbxAt46_jLPaK60v?M%oB! zhz2tiuE>eC3AdP&^oP~F45dVzyLHTR4!R6pM&UPq(s! zn{eRTN$k`nsOSU$%!`U@8pzjg-MncAk6?MU=n6=jd-)ZxyHG2(4Hd@%&gP+yA!$-H zcGzNT#e775{)7$J5hO`0RKW3AUD2RwDYTl)^W1c?AT>pkjLL z4Jsfl2tB>(#l%N^c3;^s{$PJdwiuFt2aDWP3Ou(i5d2>MMs{o3Ew+)j`TH4xvlFL; z1pQToh;}HvrrxE`7Y$Cg+b%B8G&Rk|SNIC9d4zq#%*)F|awWgbK$?*Jm*u*#waVM$ zj2aIfj4hTE38_i>_xJY7rAqj2k32A0d6e)xD8&l8o8(Q2#4W1dJ%H)cD=NN@CT8tD zZJLQhSF56;Vn7DFmvad;T1YX1hO`a3Y~0lT7e9Vj`VyCoKe&1+8OQ=^VJAjMDUXkQ??7_($of@x?VFAjf& znh#KlfY2mvhxFS9NOQdV`SWM(RVge14vub@D?2?aJL2>g|7=c&-}e5KX42&6HSiFx zcC#fIZ&KnK2}v*L1P9R9Pn>T7!$sTDE)xd_$2H%mFm_*93Lx4>J8(tB-U~SlCHFX~ zDch;25UYr72%eNYi?WK0P_2yDlQz_ZPx8;m5~5MrmRVI-+O5Abk5n zt91B^LSEX}w?SI!WvV|*km1xtUrNM1s)+m~?`hSM)7Ph&a=hguk(#-LbN#Pnaqpui zU*x>JM1TGIg?5pFcHK%%6~Ir>AuAI0IVHGm0p$li3xj?PyK}NHh~=G~`7QOHbN7Ie zgm)V#qlKUEOg;lbC!wOkD;X=Wc96R&%&Igb&-Uf@#`lK0g+HBq0nP)e%L=2+YIbAx zvSo8&zm2J1l-fOguJ_@+ro*{?&CP1O0^O+~O~(XNH4JG?B5i(O0FKT(9aI)u-y1Gz zTW0uGBPuvFyj<*|nutA#Ymy_3+u)PU9rp6_yr2>x?cB^dyWPX^7b4Qf9R4Qbr2 zcBwHGc3UQaqn!KT_!W*@A-ww)ZJrhJro&aP^_ixbKl6KUNX6{O`Sz9vGrwS9PoMQm zo=yGvtG@ajafFS&N9J&9t5@?2)U>pop=Sm3y`rkBg0gbhW|bTlAA3U;*y(i}eMI_1 z*SLe1iGE)mvR0W-S51}hfLeh`dpXqU*Sg@R$9i$m(b1UidO|>?r$B8#z}M%$*T$}l z?vf8%ZqP@5--oslO5teL_Hae>A)Lv)>e(Q|iO|PvW6Hi>;C<=p>MGSAWn>S_m<8l; z!TXhBl+|Tus;U8oI>V-2Td6dkqzuv2(1^(-BBZJK_UUozX(An_k}rUf;s^=I%9BAEn7 za!;U5m#LNw?)eTX6FKnKB3T;Vj;Oxm;Hz&9=l|^MN(DLrdn|FXr`g$Z>E$c9CYWyC z9C6p@uZaR2Cx8F`>&8?-5c9Jw!Bt$n6Sq}K^-X+sLeeAs;X`;mQ5Tcu!|{R&hmCRK zWotlyyT3K_*dSoA0eMMZT^2x$@i8=UG7b*chlYnQ6yuw6ms;!}u86}SfFiA?qw_o? zgBgJ>YB6{FD}%PT9Nxsmh=3Q^861>p@I(f9k{Ib@30R^F{(zi}c$xT{k0^y6e=qFM zF3&f=vYNCaj7Lm6ASoucACrGdOe1){?Zw40lkgwqj4#C5*zlB;lp+@Wk52r2K>Rw~ zT3mZA7dp^<57>IJeFlRaSDs2}Z{Kvu`e_tFz^NxJcE~g@lkvstbmsdWJnsnMFKX3p zT?|vwV4U`!Y4ojH>fj6u`ubJt&6_u~Nv?e@kSlnB9N^H$z%ChB+EviZikdiI(+&R; zxvh0djEk&U#}gj(^699FJ+`&QA6<-mbS zetF1v-YNe&8I8+RdXHI5l$b-_l$e;9z18sKypyhvuXvk|hxi^}r!^0=fA}y*B6Xyj zzo4LCaD4m&o;oP^IgS0g(~>TlYpbh7(se9K2VkqR&n;BXw@_9l0QSgYJko<#Sy{RC z>6Y=NZ4#KynV2wp#GGc6w54TDssjRHKn!6l&YMZQAQT1nA>qCY%+AE>`ql^(t(ba~(o>nY$w+djvP1h#g8SD4JY#pO$RJG8t zpus=FFeM2e55J*1+o4G|)&M4aP)Qgzlv_Q4qW6 z0jW~zx}*X|2;jnqQ+|v!46uKJ&RC|x9RO{MO({q_EAwQ z@C=!jBXd%{#p$!MvV@gYA4i_4zL5}x{7_a-&hz^VS&wp7Fx&;i78Iqh?Q?*xrPe}>W)bJwzP@^)(kFbn1@LJp2 z+E#B=O_qXL4YXL3eh-rVa)FabvxwXGS~cyD6&8~f>EaHR&EH*lf(@_|@21Ocdp@P^ zO>vPsnT(0p|J+2M1eP8+bh~F>avM zzR5aQ^Jt6*Rvzlxgi3k#>`2lo4S~xO4tY1=0>m&E}+&c5R z0m%@00pD;x!ce))A%rV}+)=VQx^Z>)ubQ!OL`8)lH|U!P(jx;(QW9-jZ5p>|g06G| zUXiX?N+R6xVwl|G8)hn%*>@ga7q8TP6=V~DZKJ%lY#ADGHSzD|-knHcukYD+sT4T8 zJDJ~v>466s63o;AyI8VN8E)MgbB`vL(blGw@S%pw1VTSI)&;1^_dLbveG`J50;xp` z@h;NKJ$Z6d@O~Rg*Fclh;Nn!hrlm~*)%WnmoVIZJ|9b&A_e6bj$NuZ-ncMwqA5OOG z&3u8ABh&%9GpNY*#=PKXnlb&7coX>_2?z;)yGfPzT)xlv=&if=uWmN<%m2Ag)zktY zH7R)W=8CHT<`R~cxGKQkg9DGO?CiO-lcuv5z_*)$(s78P#<#;ktUItZm)1DzQsefn zXVdgW@`>oB_o_kG?!OKKUhhD|BAy+uh==p*q^J7LyMFJ_~kRvk6A_T-H^vl1zE z`V)p%=sqDjpCx&@V~7<1umq>)Sl6e@E~|iO`@RtcDVO3J>#m z8~n0}+*yw*@BHg@vEhXBn1rg{@tO{SQs?&c8pW=?t;BN7{qgv=T-1wOVk!58+x<^# zYHCn_ut7eo=tOF&vAxA&6c;h)QnQC8n?d%_+CVABX-J7}<*m;K{n$?zzdE%z#cs7%|$Of3Vi&uCx4_O9Aunr72i>DoNACav|}-*i}T8b+;}{RS6JJ0|Wb zVhiBxwEz}z26x#!(8!%&v9u*gGOu;zKH}WneSR1a&-|U>X6aQ|k}UV9;w$m%9(Vq& zxq?pCD6eGU9dVWiL^PSWQbCK4@AI0@b<2fPujl25<>cgi2v!rAKYtrv>0OW20dtxB zuK%&0B#_Yv^dsg`PAAPMfPeTTsByBV7)>|z1Em8w)=5c8TODQlzBdP+<9A=z ztp{86q5E9l$WND*yZLaxqh3Ylr=I$F#Fbkrsw3p`AK7IJ^7Hp*g-2JS$lo0LpvgX0 zIXLiv%jH4YH;8gwhPsCl!M!^)Sp4!ECMAxkjt(W#8j<}_x6B+T1#DG73ghSJGmD6P z<5Qi;6`%DmJJF{~F$3k+stWrthmZC2E(2U~$lcZS=VE8)>%UJ}lgxrMO6*{7 zFIayk)dKYX-g2_u&7A%vSul6r5D?&pZxBK64Fs|bGpEmnO!0IoISpwNRLmnf@eAKJ z^Gen|J|mbKMPg&>IJ`A_rv8IkG$m}-Lx24(o$57m@``Fh9)x8eWRz z+uN+Y8}4gwnZ5t45C5#Jte}PX zvoYxm?a(Smv%AI;dkDn9i)yzkyd^Ohd3cB$yneTWOVoZEkHDRalQYdWkw+&und_w? zupIOA=GD`VD6rAh*LTOt%4(c5oBS()aTGlSBq3#PZa$8Aj=;FQyc|VmrnAXDUFsLR zeS6wne$pv)x7OwxayLU)dJg5NkN@uSd+phroOCLaa1p4HUK0$6fw$YkQ%8gdUpRw- zXW&e2`~3Qfx{=Xq0AqmJI<YI_{JVJN$KoPQ zTnqju$hsajhfP1qv7UfRGxBhS5u>ZO_m!s!tMs>lfwbJE{`a>oLQj&{h|7)PyJ6_u zc#{yGXIZoz*N>@BN1`b@uHt$=qR&EdZ+|eWxnIIj%FRPg*eNiO0@Q(^#X?RhYd{Da z8EyGw4MZr{Co1onGz}?v<;`p0ng^TqPvgow(W zJGf!t;g}e=z4oMlCqc+cr!D(y-Tn7MOsuRORc*37_o0jRf~!HXoPtjEum+Am73VIl z>=ZA~Z}Rp(YhxEt3=qVwKjZmZq<t-*)^2KOdJ8?cBtdxy*I9Ft-J`+N$o8KE zVkya(lqr2A1rxYbDf}MHYtqjr^gndPH$EDdBvk!OFt||&fr1#;yUhB;fr||%OOj{O z($axN8*-hYe`IIAbdFX?4Mw)M%78+`1`n)C^DikGSs7^UkQus?L{Yc5I?@vz%(yuj zfdN-g3z{7u9gHijj`lJ+Ir%II*2G+;whe=-5`VE_1)#iD;Sp(RcL3V>o%$sr_rMj@ z18EP@C#~H#)yZ*y8G+plY6IZg?$kC&Z0J6@990ah!szTVJe?5i#2d#EAY#`V<5U2$P@aJCI@|1xkjP5K5W z{Y4-ZXxrzz&O`eh{T{$}dnM-5mF2P%d@L^?1ko=(_jy=^b@dU`Y4T!&sI51&CXJ28 z{!Pi4Y#E4^j0++IkNt!tJBAcA!*cr?_j2D_T?Td%VSMNZpi>S895V;$z<{we9Mkmz z^SMtJMI|>R8QN_xTzfVz!=JcFNncKBO55BKvJT%tu-B45Xshw{f_e;#)G(vx{7n{? zb2~}|7#i`1rySJg)Rzdz*=K$J{(QFs8&RzIqau!@A7mTXcHbWRH5os7(`aL9NSmEI z8>QjWjnB%~on)-1rIm#j;vQn{<0Ia9dicoxd%fNk;apX&#kpn>2nm4*U31m4z?nXR z;@X=mMkQrRcLTUCxJV#d)SYGS>HstGyAY`jzb54mIKW(q+aG!i_w0zv|%2FoV$sq2*M-Q$@ zIA^#Jto+J_J(;Ya$b1v7K!is2XZ#<37`V4l0}N8c&_cH}>fq=u#F5OOyvb@NWq_o7 z;KsZT5Vl_!Bz&sP8isTM;JV!!e7TVD?wz%_(pBdf6TiRN4xM@|AP$TgIt6{yY&@7J z^i`7)cLah>LecVRs=3M4{m~8gg^X~XR{zsohC<^88Y&YX{(9pQ3Et}R-`a}@3U1;C zwpZTO8S3M$NV$t=2B316{hljTuqA&^iNEy7>Xw=bzUT4V#3ld6XGc|Me#B|*$3lJ{ z0y=7G^DZ?50|Nmd)}Or|-+&Ux#Z$L_qb-S%KU;@9*1geYW-qx4ym;JRd&_2b-wal{ z`9hx3-yUz=oN=VV`>8@+r+d2F7&4Z@b&C;E{SdH6m66V1Ug@r1{zEaRSt%lV@o^1t z%scAn=T90ZL#m2ON)+tuIFU^ph;a+BGofrc9M#`a!*)vKbt_?e0xx;q^>6Ber>dVd3`^^$owzKh$9ALWfg>+eKVr+7G-Z7I>Ti z6%W7AKu17r$R$S1ME5Q(;V&|qLs(`)IhYEM_0DUW>{QjlL#j#+(iHcjkR03PZ{=(n z8XB}EMV{NUEor{pt0#LY&}((xm9Lq0q!o6OYTB<*Wn{EWmMHl!Jvus?0UkpXJ3ulH zs;JO3M_K7@6_`JKM%LoVjh;<=t0_F10?xE2p)1`J90bB6qx6fbdX^;yB?}z#k^~uI zDbDzb`#-NskfKKU3klxwsIspum&aztr}E!7mi>cV=E5zT+nY-n6fo3K!dIQy14N zT?%BTW1Son$kTq@IM)oXF<9_`7px#Xqf1$5-8#8ivy-tQ13oKEX8(?Vc>~Y8&3lsXtK=@= z(C2X*daxpDYvQH?@(Id-f_9s&8jNVQYpN-Ql9Tc~mwTio7Y~9a^g~5bKI8aistQ+} z6H8HV&Y!-_@-?qaPb`I>eWlQrhEZuiiz0Cq?^puov$B35!!wnxi;r=Ihltq+^uR^3 zQKN^ALk6EUUedquRP5w>+!Cjf0_T^Z^YunA0-gc)FNU0*ZH+Pxs$&aqI&)Q1<3(>s z&8AvDe0Ytgc9}WYl~IZG>UbTewQ< z%@x%t_E`xq%MK#hXM20jp54V46chS!`l+JgUpN-bir}E$>Uyg|j)T~Q)4FlTU%R`` zU?f^r$xl9sUh@PddI5Z5a)ySquq%o7+m7Xz?sj}qzIzv8e<1U|@kp`u+H022A@+n#FhxJ-gzYj;u5ll zqq!6yW0IjziSxo|6h^-E<%*SGN@zbz^MFp?95n+r-BlcUvM}fKgsRr@?=)?zd>#4f$z;=IkjLxlKXc_3}zE0vrT0B9N=ktT&$jxnQ9#9zh2C zdx)&nx~-Ud7m4ya=~dY$Sb6D}S`7U`hY`9nbD;-`adOa_Fyj(Y58OHb^T!X<+2+8* zA^x(Uq!=dI=OCo3NxpOH$5DzwK*BeHu1?wp))tal0{4=HFR9-C{U$|6fmwO#-P!PMFb@C60PDbXoHeF&(+&~bwP%LGE8*iDQXNXtVEiH`&vIluO~y^F5iYjgs^Q` zSQs+=wk_-|pOZ_U@cPimS)2WWn6B06>2wIlE>phy(+4p71~`H7oRUp|U#Ou0-Hpii ztyz%tMw{UW67YW9yg=H&BmT#1ZiUFzIh`>!!@MlQnv0Z03QMp%lCf3uIJfz@{?fFH zQcNjiNPv?2rrdwE>+&xTaU_-Rd5Y|P(v=N-o1fp+)6)j*zM6^2IT61%&*(cniI z&2#mnQVlbMJ?#b2Wl&bW#*<5>TX>1n_a=#GHoeP`1#R;MysZg$>2>-CF<3ZOpCcJc z2#FZo{wo8CH$R`6-yHkSE9yX`lSZ)m8Uy=*Dl@W9Ly*oKBwjDC!s362`AJ_x3 zp%lz_P~UQ-MRrxVzc3OK62Luy?UYq|k%Akrtu*voP*kU`-G7Vat}N{bViy{^I1d(p z&)=+5UxN*A76FefzkM;Ju>)H*lB}~Tka0zMOv=RE`MMGTcdGMjGbR`}rreq6cXsb8 zDe+J7?rcFvIn0#>o>jL^ko`coYW|w1`NUecUV_y5BR4!MsW_{8peVpJcLSw8fC5(N z@PI;qxHkAOtNV=&xP=%;{Va#aE-o(i7YRbo3_84Lf9NTXRBbRyumQ_NR5I*KE9oZ= z5zQAlIoA|2ptq$1hPE9l6H;{-AmZ|9cyuLcV^3Qzt_%pmV?ZvS;n6t35CCL%hV}3g zEw3qgXlZE*l9z6+o9#V3FaxBLta+?D*RV*h&5EP|w}#Qb&V~l7dq7Z=x2MFM->HIV9WXrW`+|P%4@C)HCeRf|H>j_b?Gp8G2Ga2w$V{ zHwICN3VRxig#nh~GZ<{pkR;F+h|#12_?7DeQ&X>?(OiJsVCUv^okQI-w-j(81mj+~ zA>ME6BsDCU~jYSiou+|6=NgV%HqdqUr_sPxsFGcwfJZK%hyf`nDzg^DvRRxQm5_{20+2+d#|7u^en8(+s zKxa4O7#1{d6iiXh6+RdaTuP*l)pNM*9UUPT=q&={MV|sYWDbB7IZ5`UIB0=O0}&Ht zAYfRA0@Uyjw`2D6%+~uTcMZ!H1=@)Ae?=@f1kp*}n>Aj)m6SKgOPm4JM2!Bd2nM+J zk}V|^f(2iq8fjMzIfSn%Y@o3lF#N@=j^r)%y_~Epcxpc21@Zv?`Tsd9fKPCe;SX?9 zP>T+BIvGIPKu;gM5wpPi$lbqx0S&hRe;E+Q)BKkvEkEq0iR3Kq|M&3~vZ=#-me(m* zT*P*vJeu&cC`1ODJ2Mv-AzQK=>GO*W5p!)XGOhbl*xA_!#yW0;gAVi)L^fSFsG5a~ zrUQU>x^3e3h@@&e&=9-6d~twxPy^uH(D(NUe8Auh>B|$5;0mG`2lF~zfld*iVHzX^ zJbQ+Xba9wRFcv<_!p3$kAoGusqqVd&CWQP8K3zXFD0N`AJ^S(Xn|%EP)b(=_pHs-8 z^8trAwWMEtkvH$3aJYemdGtpir{{b0M=wm^|FVz3uz)&JdOfSd6?QZ*mmVOJltS|X z9qZLwx2QnsK-|&2d&u5|=H7roq-AR#fn^i_lbghJqR4H>9u@@97B#smpWKq1_McB^ zdkfF??%-5j3>Qh+3&xY&h{2E=nlL)AVe#6bvLf{|vO!R$gl*R;649yRN3lq$pNq&1 zS+<<(#!$c_gw7ahA}X=q!Ej}vHUdOqXUAvOiVd`F&GfX2%)L+dp_G*PpFEm!?xaI( zNsx)MEmV)KZ3r?TF5tYu^79CoD+-j~3mAikM_2U8`$8BD)4hJ7qod=wA4ixtAQ9wj z0Y4ZNtT7yE!GYsG@YDfK++7-HS2yNvcMO*5gbREvF&+;87BjI#pzhI)v5!}#3v8eFm{l@0%X5U+5Z$XNI1YihbcVzp z6Bk!c71#YG`7srTWZF^al|JRE-F0}iSu?qD2Yfz$CP@_(qK%$jB;l&pXy?yf=|qG! z{}+tesVSpS$&!*ojpMVM#H3THZO~*Hubq?Mq2i&zt8r{OLw(wt5zEy6_ZgbY2U8`u z6o7@thWZQsRHOGDJ(Fbo+l>3y1q9%080F2a0U}iOy$|95c@6IR%*Qj0RpAl3OgZcq z!EnPUxZ=U0(qPOBiq6IdQ7gV>*L|-B7)_!7Uh9j~46F zy&J>Q-r0He=1mHae*v(|L0=DzWfYK%uU-*>ObL#QmQwDQ!=`VrmX42)g*xm(J%yVm z0A)}%T6}0l{lT}Cl=KRI+(=wa-w8^C;QipSwULs@p^B?{#8czrp)iAr89u`-?x6Sb z6ud(Kkn~U?McjKjq;W+Zfx<$jk*^lD?gdArn>2vE)#3VuCT57w)apt9mx%IV>sSA4 zlRNR-@q>GAa`4!Id8*#|l6q)%ZY}^4Vg2B@8l4@#O*{P3*$L46nxeWm)0PIw zR&e}hC$?6~T-Ye8#%tJ^EKrC&YQJEZV zDH^c@Qy~hx9%fEUoVU9qKf;zeYvznweG)Mu4Ph^*TmZ8-!Day}pMLiwd%umM!iF0QIBA|HNkEQ9n-E0XG{LXXA=AXY^7biMGt*!7H;v&&7xAJlS1s; zj$qR9!k97cVZ@eobBFT}IMS(4WGSt9OJ^lO|c^sF06|RWl5m@38 zQ3o`^?1JY)%*2U%Yh(ST$L(b<7oaGDp@~|;N7%9HUc-m2ExFH$^G6BHq zD!i6<*Vp0UvN}3(nSZOb=#GHFf4)X;WcjWK2bLGODpNoTib_g@lUQ_THnK|y&4RI| z%%XEXLTr<-dcCvN^G4@2^U3r4ox>MQG}kN-K-=G4K zE>$2t)$&UjJ`s`2&;<``zDdrSAFRKxU#IEzL9Ul)4G6g>Prt1+l_(VsE>?9N9bAmsN!JQmq1i6|AP~#J%pqy)_ty%PyQ<6F>HRms5srpW z!);h(erv<`0*fek^ahFyZoxbvfoUCu~;13=+Ilhzz2tYnh(iuK)?jx zjS@pd@;0p^Ve{qxy3Xe`=s#WgYYX?`^g^r+B=@Z}p znuLLGvF~HAGw9DQX# zk^}>k1E@SOsSFS4Au1AoEgJ}&KeSMkNyZ8o>FS1}30OEdI54;pzCrRXIT3Jg)jwkH zZi8XWz~oO?@g&cwFI+2L{*|%mY3u~xc?EKXTAkAkM9@vCiRp-;ZyPy1Sa+OZ7T|`B zLEt1Gx>`#Yht-qGin=NZ;%B+E1-W@y{X1I6qmPB}XmrMBMzW8i5Ee+| zpwYK&xL?7dFKYmm9M~ErF|jMqOqMV?iR*9tC!Xri5`+T`sMdh_Epj5T&4ON!@Luht z>6m=_{ywPUC=?6th_)srKYt#?x)+lhRotAGPkaR#oZ%lIJ`r)&W92AyoQDyq86^fZ z8v%jwqf72}zpZrs%{ByC0|n32V0ImV$!Sk=qbXg+%@=aT;G_Yo3~(>V{Kk4WZWc7M zv2%Jmr!SXeH@+?G%$9Z1w;}!o%8;+oy#kBRq-EFZrX3H!f}x{h4l)Bo^eF(x4&D)b zaR}dr8-czL0Rr!!z=TL_Un*Gp=w*yj`*8-2EuhTgmHb_myBE6QHdXDs3~BgrL7hYK z_wV1s{V?`)JF4Ib0|!%z0*^+u zXzCFMM_cA3ER%HF#`H!n)7JA7SjVTrJ>TQl}WW;t?7qd&TBietG z=1#cd9xQ%SkeL*LTgJgcb4c%8ML_6VMmS#)xhrboc3mWkjA-&n2Y71L^!4-m)4^Qt zrLBSi%wiymlE;r|1wOasfy^79hF|H41LB^CPF4!82{UTC%_ika_r z!o?>8G%*a;weogMrjwhyv-E+T0JMNt(6~^Y!HiQrp93c#@gPgBuNo|L(J8+FTi+u$ zlMlW^FrN~fpy+TKyefs+Y0D1a@Bsz&;KVKfk6h%E>(rKO_{N1FlPg+K#d3qpoQl4kA5FLy!Ctdzl1*E7LgSLJhBwk162fA7I>jkpRgw;BZ3#; zGeYkRIUIIQ&Q_EU16!*3e{VRAS zcX12L{kt@RQn6`y0YluFQALZ9AGa+7syaMD)Bd-QRQ(UhYQcR5X9wT0F(DvMAm_iB8yv$G)p7X*GEKyUy==YD(bpnNnO1b*RUm1!z) zhQ-7LK}$JFlB8c#2$%pRgajTEp`gDkt7=^f>&BV?>5@OXs(k6q*~`EJ4uR`uKy58R zTRf61#x~#4cRPJSJ#7=*X;D!DHLgqO`JySy+rTN&fSt)}(hk~Cg&bQk0=JHtFC~Kw z`+t346Aw;W1I_4+N*oMe>qIj;fXrgLe*ON_&h|jeg0*YuQmq_tbpj=J5%D8X$lwA2 zmjEr80-ry6ZOQY2-H!ccIZ%0k-x1M_%&;hM4zuhArY#3q-4ccD+;ePS_y3=Z*Gu`v zg=-jd21zmlB8TWn+S%Rc?RlM5qVwRv8qZMx<~d}eUjSL|GYlA9R6-49^8s02H%D>MXQQ?CsXpJ*m9xaNR1ha3$Bz;T)4CB@djc1=h%fbhp>Gr;KExUR&O z{EWw_c6m}wKVRF7fL8PE~v(T@(0KY3J-Ahcxd1R==U}x$?jXJ9x2degF#W_7i6xWrGy)ZD5SZS zF7|sSI{|n~(W_5E>>io2?#`ao{PY8l9US?8-x^g~IxwKR9;)gkF=(9t+=7VfqAB>D z4xn|~0VQYwF2xpDXs3g1Gf*L63Te$3PXi;u$_)U^z*(39l0)7oe)IP8M3--1gUSE! zXvNd!Q^}2c>@qr)*%>nW_8%`eG+z)QfKWxJvPU9a|7f>Cne7`I3?)MH@{rZx<_I=2 zTz=|o(~w0Tm<-(Ga)p$qbHb*AS}TTeeWZX2&8`Gk0!-jqc*{Ay^QDTk)XrDr)wf|f z6$Lm=$&5XJQowOp#X{bCuwWyX5xj3(5`UH93-S-1LaYa1L|cY@I1C$k4YXRDA9N|O zUr_T6MK7(odVKJ>S&^SmO})AM<0}c@!!%G>p>uq0OkxFYdlXwk-3gr7u+EgrJ*KC#C)FNSaS(SdMwtN6?ks}{os0|p22ne;& zg8Q)r3MI@;#*f1~MDMV*eAefM^FB15I(TT%dN8mR0}<_mM6IRfb4P{x-c-oOuRz_SG4|iUWO3hoa$b>gRlfI0Wmx zc~&f55kEa|JzR<{4$im18qj=p75~nc&Wx=e`79tnYy|GY zq$i_#ml$4PS(W$LNJQH7C*xXmZSZn)%Ynl?Kq_h%=y^1T7;aM#GNeJk1-3cOHW2IP z|G6B2pF<{V$RD(>{icbydqg#S$6|V{^#ak})(peR(LNpqVB3ts!h5RfC54697>GRw zJr6Wa*njdWDiL$k=E@HRd2;{O7vXk${ay_LCvBytMz=`=9+~HyqO@9x2S87{epiM>#^Et(#rXvG=P4$WhJEtUHY8(ik zECiL6y)=)dsk>HBd4)xBKu~H2Q<_E$c^7x57z*5n)H7IVdIO6+wPp;ZSQ8)dhyMm6 zEgHLrd_-to0PH4Aa8T7QkQEtlH>OVIM_*N#M-!IOz2JZ5H~r+_cUHhz!cgFxr+?kw zPdgqq_E<$Sd+p;y1fw)l*uC=1ug1);aRu4gbJv_}3@_pQSUedxweY3W(Y+vyd1vSS z|8lbiM`TM*iCh_*pq7XINxxL3~Y?8II$ASf;KZDT35Xd+H&w0y`Eg2d6(K5hT zWDS#`4kdjtBL<@fpB$%4VL%*M^)91e4jg?LY=G`F&;;PS^~`{}JQR_8|I&QqTH#PZ z@*izy$&HZ*mvPUpc-W;KOwQ2SJfj=ivk9Zao4M57Dj@!~+K^9ZjgnfPP0C#BwOL9{ z4rU^A*|sIKyxT9ClM~&X%)Y_@LIwqkUK5fPczRV_m!2O6g#djwli%MSlPb@W2n2DtYLGe{nvI*6lA3gzL=3E`}0#%m9!{h$8Sk<8?`9%h2yFpKQ~xasE>pBU%f|_ zqVC+0vc6#K_e0+a04LxnYN4UN3S?;j8<_-xAz~yZdKsQh=*aJIDE*TWAYP)|`0hJd z&&oxejkkUhqX2s`n3g=0)sBl=%iDs?9FL(@h0hf=%_k%zi6x^(_FeY&)ws@g7<%&I z3>cQBU6%3g9qX-8cV$}QsJl8jf2vKri+8tqOLHCfXQ$mZm1F7EuR;pJYFMIL6hms# z2W8vebYIq*j_tXUkY|uUoFA&G2lOl`RP6(4W`H($FpvNRD?qNA1@{+bKF`}O zh=0O!`ysz=r6powH@&>f8+-VUXfKr6FTc z{Fp!J!b!;-8^Q)(YTfos!HuyaZB%)?L)1Z3_rFJ_`+U9qbXQt6gYt3j*cxr{V0To? z)@0rRTh5W1GgIQgy$H5}(VbUj!Cx_K60-!)1=x=i>3ZBCYU6u#yLZ>Lh*r^^;qu}* zlVyI@&K2FjGVORlx@-nTvS z9k}0TtVasT64`g#xtI1rD-J* z(_UzzCpU8eWfV7uuHs*lU+-yJZCvFq5yH!0~D(EBveE;f9Z?a2fp zO*_`<-Tl0Uqt2a^X+y)W{ERLQ`~2^XfxBV}R}~p1|E}D{3KbfD^S`^8irv~GtzqAm z=cN8#;;Qi_He8*GNi?U}^OY)v@xx1bmAw3os;_7^^#0`L5LwS&hH!S|PSBx&Eyi;$ zyfd6+JL&u?bmgBw>o{(RO{=7$lIDi>pjYav>lc$QE54~Vzg=S%fe zLIU34Kh;Qxu{*=~`TtffUgm<$OIy5jcVY6kJsVygpgj%^qe<-kRa>1Lp&r;(bQKlI zDfHhJBrd!hkmpa3@+&G?7^gO#qh{C#LWlfh=%~o}qs@WK)Yt!{{BLE5aKY!EY0N&} zpi@;`>zJ2$7>ukfxP5t|l0CO7|JJK+=JG40E_D9yG2FIJx-73=a3&{ReB4pIY1=f= zH~znGu2ez(R_LOL6EQQfhsgi`O=5C#EhbQeNoD~z5y3P%zdCLl3l-h?zgve-iUTjl z8hv4Rp7ofSM?2(hK7#={B$kyLvA(N~yOt1p?d%gq>c2KakRJU$Ii8K!P`BUkXyiZyt_ zM&DiL`N&0Au^V%uq=>|olzn(a2(7VBb>-2k>mH)9W^&Gogoe6rn7i#s$;spaD*HRr zYX9FQiEu1>>9yDE*>Q49&kLubC19U7tK4hTe7uogNgr?fpyW{Oj3@-yP;u9Bibf*l z5Ka)#e*p6XoeM&=1hnA7voJ`b`QP(e`}HCwr_+gtg7TG!n>^0dvTMPxrvyQ0NzsB0 z+*Bh|Dl6-xY`l9e!r;UX{>uLxWuQJlERkSN21WHi%P7Ss{`~VpN}=-0Q)e+BCWyQJ}Q@_q=|4iv7lR^6T2nPcH_^M8?lBc>ysT zQaM2$PTSq>+qZ9{5h^lFmx;hYl@lTFLm5Jytg7De-{Yg(c;WmYaY+-yF+M(P&dcS( z7EzHcEyKd%5{nL3j*LZ>Nd5=D3*6jp^~N_u2pJ`!5Qq?5CBCmXMG%_#D8I2l)Em%V zGXo|@2$LNYO4se*M-QzL;aN}Up*1${pzpc86>4(9#_Qinq|B|zw|$Tsc=KY>K~X^) zos~{_AIK;5T{>?dCgq6YwK4pvV1vRWg6tx~>RY#-adz8J|F@3}>0+0~;~G;ueH4Z@ z&3X5~-TT?Qp;v_?yPB77*eAe;S_Fp3ue5WDz}ON}b&9IzaS@F`8E2T!&bpe<=Ceyz zc4nUwmJR)TB_8I;xrw#3)@&|%T^7$4Lcd0st;b`xxIbXhsXD~MVHpy9T`?$=tr|vO zyO2_{R`hY`v;hQ6Fbnve^61}|lh_wTMH>=srbpkeLrIBC-R+vr$PDY!%uq$1EVX@J zCaJ4C?~VyiqzcncdIJ)K1yLu$6e*uoA;}F`RG>`!f?cu0``?klqwF=8hxIv%WMf`N zI<`~VlgtVA_&9Edj9wL%=&PxW=vQ!ovJZ1G@%t11 zZ4cRII6T80I>TBq6)U8?!*8PNu;*y47$c98rAKzZo0h!bs!K!*WUhW_mV(F)BP0^- z9+ya)*?(Jwo0g1FYP-7_@$<1smp=#RO~GOGs>iU46Vt2i3jFvTOD2w`F?1n8!Dqrl zWc@|5?PLv+q@eN;jPbyPS9KOi6S%Gz5x)A%OALWwBUS(1D-kZ{;GDtT?;@PXs`@G+ z&e)=`X|i*ZT_3(%+s;Uo!aloqVVZx4`Qf&i2)R~wHX>~Rui_V-7lN)U!YhejDFF0f zUWl{UTK;#mxJf+uFmXAEPI#m(B=I1S<9*&K*?>R;TOIMd(?c|zE7+ET&D7@>7 z4iT9{ARa-2xWHG5Agw>=oQnnsGubu(16&5g3SM(UwSPBY=vHZp?I(Agk`~zE10D6f zqFC4!=4?=F6wlnnvV_vJFW!A*-%GCk&Ww~K`8p@L{Iki;_I%VQB#{-I^IPTIzCGeZ zNP!fbI_bCjoB#Vz>e7Z}Tp@}rd}N!p*()o$AP_lf%8S;Z#Ct_{$eY|wJht|e?nOxO zeK&`xYGMSZ2LI9?xtwep=seIcr~|IDJyHF?E5DP16%qL)k)v#m_QS!|m>WBE{Vz=5 zxF}z^^~GV+OQ{rI1_B&higYyhb)k!^nXa(uAh|^_0W@P5c@3}##DE#Mz95DvTAYRO z&Ex;-gthx@?I^M~_84NL^m&=WQqMZ{tiC=R^j@K?I{EfH`IYJJVxl)^txTMsWNNdv z6AvCipr0||F9-?l_fcZ0kcx~9Myl654zj5QG=g^SQ?KyhOTLm zT%v_j^Gk*2Kue6(|J6n%E@BB%b)ye&^GOP}-q5)329biX$d?B_;;alCjNV;oJ zsyJ;#<|^umaPPkgC9&^?>zv}ycae_YCf9;smn?|Dt8f>)(c&wD=^+-&wYr~fDhVhz z?2~NV+=vyZ*-ep7o`&TF2cdVfr#&+@e|I@1gnyN#9Fv11)?dLtL9bzj=sdc zC<1i3z_Hq93AF>9>O5On{un8NYOZ1}WR#}pwUuD+6cyb!2%{4bnS#q=VD}Pk1yPy( zeK&Am#RkHD-4`v^k7H%4=Kty(ucmev_Cme(;WI<43y98%zJDh;X~E`(0@q!8BcYFb zt7a4_udahF-yDpB(J&*$)qP`jP2`3m@D;0J3q$;p*N)8x|Luf5yP?rzdBd3BygaN} zk*c^SA*fY2m3zonQ))f%MsQTgfKcs=OgN}>|}Qo++L&i_gV zVFnyxNpe&bD@4b`& zGV6hJ3IY-gWj0pXcGuAlrcNgchch!5-m+eNWU6hwc8SUT_{M-g{=i2fr#7s+nh8xK zuO6~a*2+5kSCF_du)Qhc66@ulsbqX|0lJg^9V*w3=)6kl2)wp*@ml?)k#Cqa#=#$c z>Kscb9pGR7@KB00w%d(KD{~(_IGTW03Ft39?clhrj-}TPF<*Cf6t`t9LtIlxV5zKc|)RS_#Z z?kO32%mEKPk`a)UBe_{G^$xfP1L-=po`%;#uteJ!0vz5aWzWC9>9x zA{+zh)h(G{mqh2Ed8IiyiTDbbQKoRejfC+^2p}wQI?*TKR`RBb@?5o?NsyU|T%YA0 zP$PSGC#c9@IE6+*a40HHPuoB?c$qP9`;73-hp!`oO^-1nZ0U;anA}eGB|y+ z!B%}Nm&syddT~VqH%*G6U#j>SMfAK(sFoDAL1YU-brdCCtd+az%qIZ7O2GyQDARoi z+)j3bo&1SAlS+uT0xRDKPkJ$LL;VOTrcWz>YvTo?9*^?K=h6_m)5v_ic=$Kq&ZNaA{-0)(cfId4`{`Bvq=6$}^NbO5LD6`t<_!#h4xZG%1w*rLYNwkD@f>N+H=e z#giKXMN8M$QLHXyuaR9JMp1}{4D>^0-{o>HkX`I2{M2o46YhoQPBs(F5zOp&DVyLp zT&=fbQ#8&9!&}d*vVmoK_rUd=P_1S+vYOXIm-muwWcT(a%o_cJbK$fC5 ziR~0@bu{KG7P9oaiJ{+``d89Tx8Ne%B+48j&5CRCIa9CU8^kd7TfhVW(iXXGGc|U} zIRf@VuWvP0a!-?((dsZS8fKXE*~>V5oZk;@zww-v@ryskmufuR^5`j5*6ksP2Z0}E zg%XjAKcDWM+KtVt#8^E?4mGUFCX{{FcSd*l!4RpI_l&E0S5d+E#pE)xzkSp- z6N2hrPw|^lA;CeK@;TWpm;6b+pID3Y$Ev#h-4lsE&Ye|UsuZmqB}yu~J|^6c-5|cl zlFOa8GSqqO=Jf9;cRY9wxGQIQKFM*V|6Q(l>WJDT6GJ~6*5rEa05Oex+ZQ`wNNbL6 zh>KIxRKne-^6kccQ+S9eub#y&vRz$&_4f3usL`zFMYL_fM9cn~xX;>-^JHak7oUWZ zUoz=8eK7p^|6ORtGD&FfQh6JFtQ99*7?ZZER&{optGJ z;{e1BY+es=6NOCZ_9b+d_uYJ0zQmBFWZhOY?y~Q+cA&2hUA_Kj&_>=zQs8#$=<`<# zB|dZ~JC14hG_@MsTXUZO`;qNsi88p9Ke@0*bg?goOyXIyZDCso=Et^>%%$Dd9k1ob z;;C>`b)}VuqMB7|!|pLuhvo6Duw>F1idNqf(`dhub)i-ZD^ufILt4^kt{(^HlfPH| z1c)PIFu6q*vDN;!cxj}lD&Ly$+qjsCge66>h_#^43JMrh$0xJ&^zRGizq2*;R8KE4 z3}Z8SqHS88C!oyNMb3eHet3NSY<~hj_!>SB4f7*6Lw^;zAqUkA2l{8r0_LWiH$LXn5g>`N=aX^ltyi7%`oFi<7W0u;=#Jmt2t47sL%* z9QA;DP5J=Vs*EALZJ~nI1}Zwz>efk98boRm zg(X5lJ28siKN?hQYW4PhO>D%tLmBVf>10h`K!@ooxfibb1E<0Le`|+F$CDa6$RrXE zQ$9&r`pH06qs7J4Z%Uy#pQ ztnOc+PAC_-Fosn1tu^{R?|9zf{1K0c!{C%L_p(RdQMbG7lvbo>d8eVI<{S^-yc6e;?Y^luX1rX2ud=>o+fzuoV0G%Q&rjz*P21< zH)UF1bJ+hDo&bp{qiT4uR2Zo(EuK&_pI^bWvhIC0rdmV?D0l7*1YP{$}0Tcdvum%$E4|Wqq$OWw$-8fS7Y3_ zuS8$jK90Uv^x;uTzg=r=B8hsFwlUkZHb_~xSz0BSI7pqlX%f6F+)9-rd+v!HHM~G= z&akuOl^^4K^D^As!!dcw^ijWZq{&iyqYs>MeC4v}h`hUaDyODXkw)bgb{Y!Yivu8WTzau6jxGQu<;#psJ(v&M7Z&asNi$Sis?a{q}=^-jU^GiEE z;??@jPfpfJ6@G}sBu~|^zEHVX%YEP3rljn#PSL^P1dk7IF>(&OJC4*i2S(<>&tm z?@zjar#QjSAOgpZ7Bp?Zz)KeMeg(8vC8emgufUK1Cr??R2Pxja-vpy7m!tRmhQ*`X zelbkp;svKh2aYHdi0_3!w)nx}N9||GG)19yeHwD}ZNKy%71&)d88iPvD6;p9Ei4~R zoH}QAewUEWmV>As^Ch0#+yfc89HxFxu6u3@LBAtA7I@@VZc7%KtwytSi1^XT6I&B& zl_aG03Grv2yHbrl^kYz!@nxab+5h{EgM5ZFFMg}sCPjyQa@$g;5QED{w)_Fpg8kSp zvUs{H+Tu~cgZE_|xxCYguCt)sPK{;{i=76C+9^15)TeXAbL7;?5Vaw~`Gv71mK2N% zYk*!!E$E>Cj$9W#>->VE?6zW-=^R%uTQd9lV|s%dUzr2#x!^ujLb>-_vz@$qs%P_c%)543;} zAOi&L(Q9DA#Kpy3h?l5ipQ-F(ULQL?-(5h1e8UP67Q$C!;pUD3&?ym=))6p*PCA`A ziZWvqb`0L}n#d%y+sb?|dka~PYT(&pIKZ0aF034gN0y=P@{P8zJhe!NW6Y<)5JcT| zPmfYJifKE(6lAeQko4VbVAZVJ z**PcPhen`yx2oJREcD0hC*Qd-Ei>Qv`wcHGr*lTf4CQl6mQXC;|9m@_`Jt7gJe@PV zU&w}wv`?xMYm(K1j?+E%RX^Gt8&BJzYjmLb7V~w1NV$OFYkj?#L&I-i^69U7_5f3& z3lh)}G!&NGK51IcE8`$2k%ssxU~CM$rf$$K>O#B>kTiH?EnDV*$9)2P7(^DgYzHI- zx1VD#f#dU168t^*9j3;p(|95(&R3R~d0iIoYZd6sdG;Wm02xZa0Gfj|&*v->b~q#6 zEq{xD6U{WXo9C?cU17MC{MRvi?CakGbLNaPhW<1QZp#nTit>NtRc*;u9v3gENf%^l zEW4dm+HnX@3q{et3(LADa*+sEX4HErq><0#+rC%5NdA^I8+)x9ezfJ2G3r#E*XT7L zn~J;g0%yZh0|k`&<=7Jjgj*+%imf#(^#`L2QwEyGR$P~i&1O`~OJ4qJe#B9w{}PWZ zB69~=cKZO#Wkq=^(A)*xI6fdke8=h^GA6EG)hal85As>dx#kcHmuS$(0lg7a^e^GA zlF17%oent0nj65fOEhT)21S8>%`5N=h=$dJ+z)V^`wAS7Ugs5;8a31~ot4L+wZF2D zBzz1gG(74$J33}TO@U0nfgg5=;_-Yzzi5@shO3dIVgbb9i^u1nX+kn=!CFcn^ITLe z=Es8WmIu31d?l}2?jt%LQihzu9BjC5LdMPVtHOcf zaADGE>$)tytwW1O-aVa}uG$$ZnM*>I1X|I-QST&nH%O~%<>^MR6>t=Qy@^1>jgc?c z&Sy3~%KeV^oRq$Z3TaZ^DuA61{*Ztz{X^~~Oq`(^vUvAJFGXitnR~Vas}UTSz^;TI zgqIJ1_5y}aBA^Zw#L5#WcoaI^)kf$0zOWc5xuY9x3%iHZd9e7Pf{y{Q!BM;fX;_CE zSqNBEAW=+Z=Z-&W6Ce;#D9xQKYsy}8v9WexHwuexj#}d2Dt&HsT;CncS_PxD3$8$D$d7|dhCt=wGRl0+gVeBPb!-`4e8Ss$U9xp??6A6YG&hrIw~||c z?2{*-sHo_o^9Ar2z+Fvnc6xC+B2!IMvlXZsK|Y)2jle(>vq%;H^p^BaB<$o}Fauee zthx=>DV8Ag%BJj2!XWPTeX~L)vjZ_^hbVFP7hJ(az_xOR=|Z~y<1Zc{sYjO^Jiu;Q zSW7#|7K$V&4TQ2*R&D(UXQA=NHWt=EHF0^F>&HQN-E3_7AD0-Ov50X5lcgMLNrYt1 za^0Fe;9=4I+c}XNp`tu=I7FXyh%P^u9r80B(tfE`jH_-Lq3V}Wk;E+3UyoJf(?9mS z{E*55_abUtZ_mdtE2v0q4t?GyFzU&6Wg+s4teZ~*c1B=T z;;z}fJKHU&+z1-fp!d+g*~v}HLs zDXS~~?KfJA*LF5Z+iMEZ-%VwxMKfaHX~joSeap!t)LRjG7rPFnAHaKvnmj(Oqs z;)V+9X@!r7I0IpR{v#co4lu;*0+|uws~duqgYQnL`Hnx%D_%HrWT7x5IuxJUbh%Sx zq1NNy*T1t&kT$sa>zPgy)Db4+sUpwBQ<*|?w#Z*n9bzq- zGWsO?dydtIx-3_|KQ>?VC*j&%>pq?OTiZ{ncZ`cKEF=_sbKoutL~cl$su<);TQm=M z%T~xmS|@4UBoma7NCooM`e?B#xL+BurB)EV{9OT}o>Yj?8FIW0SVh!R1T9zp`2z9T z_KXIxl3V_i;-I&8vFp2pGlpAvy-;DYDcKB0tP4Jovnl#`LCx>j9=Byfw~@5Kmni1k zRx@|F;UzidE0e0C>m5f|_YS08d>3mYpFfw~WQ|(|6$>knW6eQ}Y~py^yl{f!&-RnC z5@sZ!x1hXl9tI8{zz>k$<{Ki)1HUTp1Bpe;g6i&eK8|M58IWSjczU=go<=5vR3^9N@4IbnM5l^-?yHiHbsXbo}UlsV(x zW4ViNvVoObm$VxRjg*5=)2Qc%dd3S14u83yzY-JrLb_hDpVE($>Ex8ViAjJk@b(mVlF@%N8gDwj+iLa89lmImk{8q1l zJU*5vd4Kc*wJg$-VTAWI38#K^f5A>Z$`(~l&6AZ%l9gGsu!|qjxcY0}rH#j`-TbDC z4}SD&a3H%xtj$VgZ=&eAzn-U1caK#*ai+#RtAzgsS<;nt&rpedlhc+G|4`xp4oz83 zrC6IbZu9zkuC$X?*mFW+^mHnheh%Bg=?qonEO6zGfog3MuHqe)ZS&c7I0B41oHq)q zzU67KHZFX)!cP}W1b!u9P}#mKR=k~)$(D2HS{pz`B*}FB6Ctn_XJs;|rrnP+=6lQ> zHRLV!QQM8}xj-8FPSCs#{~!DIX=g$P1Eyex-7Jk@sUbJLyLKHxe^!Q$e(u|4ug2@_ zbA>pvGWFX1Y&$yECLpdo@@CoAD7@t5AMh*U^Vd;yg3t@qyaZow5h0=Yw%UQ5e0HFM zBZI3aGhgUYsBZE|-W9$ZH$uSAC=$wuZ(wqfu4&!XEah?gV}0f6`Hh2S*%1ucJx}D8 zUyIt^!2kJg;Sk>kw8D$M_V$X396y~KLA}Eay_^nNHiapdKC||;ib={pU21S^cpcc7MF@g46xs1aKBi4 zg@i`>IUg5;7W}Of5&n`5NPP3_>;O?Hl|B?sRT1*%ob^+hBaJ~1{V6Qy^w~;yD=yMrNtdMRr7$a27>$YhNAGxz z#DUuN3VQ#?MeP=j2xfhE8iCyIy7HOq6~>|%0sy8$t?{Bx9z0`~nj{RA*p@CgRCAdU zV$%Ouw4sn#RCht|?Bc7W=h?#k-@j&1nDu|uCPNfAiR2tw@wA2$c}_iUGh&*bg`h{_OHMD8CGuSQlw#(T=0{ z%xMK25clzu>5`HFw@R1&aofNS;0ldL z*r#Rbw~w3rzj;0sKK4&SS2JfwB)i6{7Ocm#41LXbW2$PShDrcJ|7%bkzU2_H2(ZXf zh)(3Qx(be0*TKeQ`C6*!dkr&7LqLggDVnEM19*6i8aF$Fxf7 z`$Y)m{=8=X$me&iy0Be@X*8H2wW1!qsiUMKQ@oO~i`Bj@7k*aT+TDP3Q?uMka=-l56XrYu`{Jvd%^Ekac7|~>rmK31F!cXBYvHY%u)>cn zd(IrhLBqgqKtZ`jYnQ|7(V~Rnzxl(J)^6mSNK2s2i6|nd$VTkARrX}<8S9Q$gXLhP z-oE@ArO(D>zs9~y4sC{s_TikQld%BVl3H#1HKrnl&#MFmtWw7tTu12+QBb2WA}sw#W8!h@uHE@hnQ%s5@=3_@Dsx%ta*=)F zZjb{yBrw%{3y02}M;)++E419kj6U@)T)~L68@I$33oVFbepXo%PJWSLv+{vy#%2yi zw<~ew(^Go~^c*$mzx^CXb;IuECk9D37PJN=RM)JvXpMoN{z)3zM^Kd?=F<{)~l!t}hZAeU>>kA0G( zc-y5WNb5xf14n6uP2HTM!A}jc5U?BAYsR~Mc*;cuP9sPn3u0aZ8kFuO-WkvQW0?=Z zG?E80isWCRHTm6=#2=9Uq^|JPC{$HDK8Zh6MxERqOfi{uE2@u9}@+kP~{3HzQL0e_Q~(w~=Hi zgeNw1s^Z6t^+};b?F^}EqER1t$KUxWl^Fwa#3&5LzXm1TMj9{7b0eVfa0SJM#hvRTOU&CK{ zdoCfi<@Gawvp`{v^sh%Cw?Z<^Ks2zpva$dN`u+P%!ou(1SBBtF5%Ju52(JGiTIZ1u z(myGqeK|aAC`^b@5|D-s;IVX!``FUZ2T}2wV}sYy{^L6(eeMVBmEf1U2>skG!B(wN zcSKtUy`Wt-dq-m%?=u;8P#OSsh7$`=8b}c+LA(JaEF(BeeoRkqqLT~{59hZY2!wNE z0KNn`=E=ap(R+q{_|Yrb_O^36k2&Qy1j-?$6GTYCZ+CWeT?3#Ayy5wkS$KF}f;wO@ zQyx#R!d5;=#k$@gENB+8`;}L)_)>N`p3S{l|HK^C!AGoPFgYi`k1D>lhdM zD-OrMll)YO`XLJb6Gr~O$q`@$Xbaa^Se`>S6>4z^z{6m*vl)aN^Z|#b6GU=CP&F&F zOt9N7HfW-~%4oX}?yf8??Lr@k=yM@=v2I$Idnc?6kxEZ|WY|^WD|QK0EWr7@5SvEijTe7u*jPY=4`gjp%3H{5()<9z#jCfh zjo~D3gNwXR>m_sAf*pScU?_N2Njz5fNhXCu3zIML>m9n4-uH+saJe)O%4qs{g`Sak1z(t{*O0}6L*e|m4C zU_%6!^3SQ7*WgUc>$#;*Bk0fr@+!o(5ApeRTE~>lO_n}(z86C`*C)FD0n{w|K5HK> zFw2KU>%p-TP9}1f>0$R25WepKvyOz4(kfti&#_eK?PU@p-p^&QEr59wpZmHd$N>#* zF0mx{%M9_yFo@f7Q=PzbUxMw>9DoNfg-M3bxG>xpXeQq1k8eL-7J}3oNBb+TU_;5f zO<;vjPDWN@hQ5mI9?<#Ne9t9@Zp8|I8ChhPWWqAFZj8{WeA>JSR>+cx_L3k|dH3hd zsE6`UM}I#nENd|NvFuA$1Q?DQ%nZSvZVt#W7gc@)84#e87V;(ov+R6^p9oOUZn~|1w=<4Vv6~AU z!lj<(DmZtZZ;lwbX#KANXQPAd=}b@DMD6e{VeLbDDfY zer?Yid^&d^vkO`4;2zfoyd}G{-s$E1_P@Gee_t|Z!t+JKWi7T;&x+V^8Dhi0pdqpN zip-a@s>ai3@c&B8cwQ>@cH%gnPBJNb7ap<``1`x!{wg6?&pteblQID$*iwk6oswf>z3PuFNzfiFR3#RH}{ zmG+aCXT2g%lh+3pXkq|_BSsEATnqW^Qvox}sR*fX(_DKhD-rseECzfxr?&+Idc(RU z1Pmk7f52>Yx}3IrCPh`LW!cML*ha-VQr5o7mftSPl17B_=?TxMzAFKEGBSdPR6vL| zcw48L=)AO3&Ajva>DiY!s8so%|rmd^Slg!q4y%515qVh$q7haLw zN!dp<9tk$(eujJFkeLC_6p9ZXEI{dYgOwGn>h$=jEykV%Oc_8sz5nU+tx48kW4QX| zdAamtpCe8PW79`eagzOcC%y$Hr%?qAjbO_Usg+D%iq#9-%SrvjAdRHUL$DEj9>(DF z0&7Y1I6{af&G?t{`5WN6^`aeJ03zo(+0SqX&#>-9v)bVF<3!_F3po21edg_k2Q6a+FeLas|U5({f zjTf9%w|T@;lm15*VcZbRQ2`qs4Nf1jFBa}b_sxz-A94odg+;mtk;}xL_2J`2h%JSd z2g|7A%bv{d_Ze>;N7_u)7nX`_zfcL&3mTRx$1OpIBfu8k1JL|^bJG_RMuLLN{D^0B z4P+A{38N3Q^l&S!sr#QrwF4~`@ijxz>q_8dDDO=WppZ3~oLDAhRoMai&~E@qAztSC z+}iIp1#HW9t?EmT=&R|KH-0{;pm2(b)|Rrdw#&Wt|C znLRp4fcx+UIe0q$w8Ed+vyz#5DamRQR^x!}VvC<^)h$cKP> znug!nn1Oav!h-Q_*(L&801kihyZGr1QPH}IiGZD1X$J2_VvxBu!KQ8P<8NkhmV3D% z!G38QH=;aE=^s6!q~GOPu+^GGst=VdPx1rYXGNH|2f0{N@5|{Z-%}}x$b9wwb=xr` z=S8XFMal*f>y6~0kM!HUM)%9L=)0cSGDL>Hdj7nX!4@D!FtRd%Kw`0@#n-?`f7e`` zA5Cc|9RpiA4;XKQ%PXVXjm9!e-o(+u$7py7dxNm>PQ)6A2Q6rekk2wPVw-z z6UyfkdqnaEqSFMG{0ghbg`vngkl->hF`%VE>bj03Ucjci``U z;amPgr^~gJM`Ax51VO7S28HlV4vtSzRN?K1rLh^%_=49i;%|A{u7)zBmvy0Q{5|qG z09Bq9^5Zqz+xtEczwUTlY^{AkqnIigIk_yvB$mKB%y-MGO?6tUk zP6WAXkv!x$zOUQKnqY+W6;=VThau8UU{#A@jwH7iGU{-kRpxCVBj=%#T`~=&UA830 zhpHFx28IZoSV)eoj1uIS*jJHvQH1goDjMXEEW`|X({^FB1|?a`6YV>otCNF`sGCea z{02tFd22Xn6usyhaNtwS-r9tzEBrj6gW7jQm>43W@knh4Stt zQ}C8YlK3o3-#g*6+4Ut2GvR46$rA zap$qYXn15~7EBHT%tS`oJ(vc)VQ7F*+rT^VG@>u0S%RT?O?3{}{heqXyxK)y{@TL+ z-4*Pt{j28jlOkMWLAaWTERam=J(C{0aPt`{z^8{jY#e z!&@UsF=ctyc<1)R19y!~V*6FKVE|SKbQU@;EqUn~{kbNd@p5b7R`As%DK?7OoPkT> zs<{o#8l%ytqU5NLZ0DG1#YY$ydLQpbRPNz7`)&ac#EKy3z(%-MFip!Z=8PESt{gq;}JiM`bd1bAJj75}!LQ6PKVl!NET$?0rm+N8Vo>!Zlosgf*&L^(o-+h~;W z!D)h9vilx`cQ6bYAX?janL%_W&DclmxAk{z=UiK)oHTZq2E-n3ARom+bN9)rU_WTEUX;rjgwh{f0={j zZ8h=PW?2Y_eA>>w_=oir6n4->-V_w9lCi&xBpJY=y#zj1D{xF8s|CE659y8c^?Q(8 z1pPOypo2M#ra?V4@vAxBQ+d47D%Cp_dKNy23v2A1XW2a8`&%{Tf|QGR$NnR@pGSP- z($MhjpA8(PAbG>k{8_ljnT1Fht|DM6B&0|d$kT2dDk>}A;Npq~3#L$TrA~w27=o^r zPm(ywDga*gt8_w5a3uABn&c2v51lG zC#%Y)_ur{x&Ek6H?yKgR<8&Z#HVEYx4JY$Izw(<8JS71v)`j&11zx6=anH9LKgW;*|zySsXg&^dpiAwti(89liO$Z5~ zgZ*n6d;7V5@q2%Rx(b@f50YaDD_-Ej&dE{dfrfXQX9Brqi!g zb=dM4%eXGU0(xfCicW%fu0wAS;ltN-38AWUDbGYY3a(&Val{PMdw@jZ?0JZH{TU#Ip!IUGdaC0dJ?p2BQnPG%~w-hS+}A zT&Ye`l{l5>wJnDYB;r~si&ay+wMwpWKUcKKLI6A{1ABFd`Fc`RklH6%Tl5?_!~Lfe82@1iOB*sTrhPt2ceW7DE2`2F|6u^Rp%+M4i<(>;J2CyHa**}FSO39aJ!5p59;|h z_TT(@m5|T|lhEGLAS4#=O^ru^F(tF)`3WDP_%9+NLto(>aHd+Iy;?8+ekR^7c=Rk)il zMJWd%$7Mo>hp@Ybpw&Rd<^T8B9AFoV&}r|JK0<|5Y<~N64*E&hHyeY+pCW@?C^jNt zqehIOpa$2@t2AJYuZ$B~< zSvpvKj%L|7f)xyaFCe?=8zS6qIkKZl^JM_{HVHV{y$6=Y8-L_C#Ihnx1Tz5;t^trK zh(?mc<_YVK8$8hbLnyimgn90GiCK=lH>G9O8oc)O?YumV695vhM#>@M8i6(dKGH7Y zxh`%8`AWg>9+P*yDD$xamupxA^#IN-Et_{Xrhyj>oclpA9E*dgc6skerOu3*V|jkQ zWm9hA}vVVbK?+vFp+8!97=XU z==Hv)e<}RF@{ku8)(ZnQO9ziy%Mpx(Id#i|!S{(N7@Jy)Gh`HtQojiv*E^tGMPw!l zN0QUa))u`tvxYjm0L}w&7k5FcT_0=s3qCNWTT?YA{fr3ymiF{a7|uJ{(ckIzgm*_4 zo%b3Hi{HYDSq7CEh;1WER$@Osc*|?mms~wc0>(@}gg%YgNp{-TGd z#|Gh{XpJk(Za)e>kP0=n|8=yN#eSxSDf7pLZSw7m?$>Okg$y*-iUw;QgQ0=!ZC1>Z zGM&cN{r&ykDYj4A{TbiuGV|Gymw;6@mEXuSRimwhRvlj5YmKnSbllNCssiNh4rJ;e zbq$Ra=ns2jq?mY!SKZ~+d#-T;ssyf539#N@$Hftq5qyi&tM}poG=*aUtICXg0$^q_ z&>O^c+n?VkM1LO0=e16>L+y4&nJ}(D2cS>OM3>wEZPHR)6%-04O;^FDmylzM4>%t1HTHiE zslK1@u4TJO&M4{Ps1l2Af##=8KT22aI!TRt%2ow1PSX%N^g&R znX!Ep>8iW%A8-Q|aa(PIJ+C8La9U@J>ebV8K)5@Byw%LEgz7HAQ*BwGCYYSe=yDFW z@&X0Ql0@prrlyjteFdAB7(vKKJU7)fuCc3wcAn167cw@y8fa>~<=gSdlXcu@$SMO(c5L<9+5J`#SrC)zYy!4+T`yFs|u?|E~A+PnYjG-tBs08aK5O zr%GHbd7cA){R&%@j?6JQS{hH+djp*l>Ti1*e{y?QrtS3ZrOXc>f`QRw=({O!_A5s+ z!IvQrk|MGnzMHQKbjn8u`d{Sw?re-*fS6Et4%u@Y)}Lv=q2R{ zRV|#DimIwP@akG#Ev1ts-}QPNo3QO(qYt0EK2q2X)fd&>CpzDcUyI9_gJatX)PqZv z;1&Xwz%5X_*nImCKJKw`dXM*MZoU#2bV8%v^Ik9(y8hCh(gP1{W`sHnv`z_wM$v9u zRpOL~Rd1|4e)6 z7TbY%XoQ5`42#V~Ns;s2hIN^*i{1jt3qZ88#CGGPHXRNbo)vXjd{N`FCH85jG^|`X zO(F$a`nSgnw_-q3jo~1{xMgK5FngW%Cnpe(;ii8%-V%kAflTWwJu@aU=>b3@{FdQ! z>fXI=B)6?w4DWciwrHq8mk;hE+#O}LtWsY4HyJ@P*gzT@*2ZjW& z+dnp=$Se56#Bp$We>RX=Y~y<#>96Xfh#&h^#$Pdz4zUDt4ElmjNS%Z|KcJ>;FR_cM z-=5MG$!rFDHA|f}8eqIyj(L|HmsTDvcD@GjvOvM{`nQjG5Z06fJ?rwD`y)J>x<4}~ zH+}>0x)mTO#7Hbte7qR zy>|dx13KvV+@cD~p62DQe))0bQ|j2eRa+()su9-he0I#ic;w|Vex0e=Uu@|{NYO^^ za_N+;lxbmvu{;sR0KqO!!a#}(YI^Atjc!{k3>?8F9KL$a0;O~aaWnSYp8o#ggwrba zQkppE4dE1)T-^PpRtx?rb(G4Rzn`-t^#uDDnN@YG^{LJAp{PXTW1!DYyCt zkK5_^bMzu^Y=mMvQaYoFf{qMe9m?Etduin_lqkrUYya#yb4!E;gV*P(osz2Yjo;s( z3xGHFQTBuzkkKv~L%X)b&41zg&6|6mFNT?Cq*8dF)Pi0%OUKc|;qJo2cf27FZa2gO ziV7sGq>?_o5{MWA_~c>#Pn)0uTMl7z2353i-gV?j_~sU(yp%YfOGPS$eRp@uu;Ja! z)Q`2Y=bv(C8BP!yru5MsRBZe6FyevOu<5{Bt;2H6Fy^+rvI326S#@jP-D)#p8*4Dq zd;_s2E=R!C}Qg9J)Ln?i}zs1(SvL)U`O8!P{I*ByIwo(;LOa- zz)i8?`_k08;(HPRZo*+U>|-?8#C|#8aPA6BL@!_(wGOzaz-(ss>G_|hkQ;H)BE zdd(a63>9p|1M^D!%mLEqbl!NIcnfE)Qap};sU^)q=r;h6NR?f)ni*LQP1z9)k9zFF zBH=?md{}h*Ea*1bINT6h{WOo||F{4vHd%XF%0Ia@QfZq1c*Xq8D8Iosj|al7Yr!$u zVSUh$SY=f*52%w%KMJz_^5`Wwmpm2Y!-G=4g(oOZY>R3&d9nLBqTgOfD(`Euhxn;{ zBhrJgK^x5wz2B)2dIBD-MR6Bx1hfhnE>SB5tPU_kSJDbtgYtsGnL*Ldu;*guu;>_f zzAQ$3`9*}(>j8f#SHI8-*tW97ikbSDbC~i^OmZIIYJx$K7l4Ft7oa36O9q*D9 zto-t603c!qJlsNH%fZ?-ayfYll^j5K?LUk67%a|#=MLu-u)(ilQcRZF1Js51WA9I{ zXR%K{A*@S*f)1R3*#s&1rd%IaoL#YIXo4El@=UscE093r-SC0ixarRnYWO`fN=PdfF}3?Oumq;E3iQggBj_* zj<@3ys`K-78vd=Hu(QMIB1j;x(a?EzE!Y@bb1WGwa_kQ%?QX2E|3dSZEjQFF}?uQ=F~JHi3FYP3>fDz#}2ut0QS^)O)lr}SR2EveE=OZUc-Yg}I347ktCb{ksMBRHPhi5lZ`(p^3$-5jk7$qXeHe zzMBscBYE{`z@30O^Soz~60}_W_7m|?u#P4MF$)lUGI8y|Ps{LZe0K_PGr#9_r5!*)w2;?_~GU{UX{_0k8r)qk5XfD=Pf z_#=!+Cx~9axkUyCI5n^N3#0oM>HFgZ3O1NsQ*FR6gB9HeFQ9IPZ2~o}zV35%nhzHc zgl-0`lA(Z~x~ok&vLOhNp@{qXVFZ_LFy+oX+2- zjia;;H7ZTRm0T+}GpiE3=X_;5K`pDUjwnMs?5y z!n+fqdYic6REq{Q7{TeJuRm;MB4 z*o@XOmQ8kEE=9?_e39`+!l!XZ)$1&qRATM_+4W;9x`k(rc-g!B7$17O*~3<-g)$wrEaR}T>72|UbJaM&;XDZ08v zvvXiDJp`iP_PEPE$Wu9(6FQB*>dv9=bs3f+ayK4Vnf=**1PI}hSn)D(hY1?cF?jvv z0a@86W-G~Wwx;>HD-EdA5;O%*;F$(&Y?$sD_o3`t7|1kAAAL?ZEd(qc?vq|VdAe=U z=`(=LfN&b{nTk8+_VEvCU9a+#|}UT&e-#_>pszp)qn0I6h&-f z=$3Q>%1lZ`K10ZfF1{1aDrFjNF3H6{xBCHv=f*2ARirs9*xPY9KahQ^C55WIOLrrx zAj|VJe@bJ(qvXFgS)NpK+pHbIQ-&-6{0ZRG@54|H{KCX5jYX<=@2-p#GXiFuw?=FA zK5^hKVKaQ@fCs@{e(6SpzhR{b{RqQ7N5j2D6cI5oGRk>CWKAE@$6dq3s8R?%aDgRP zpjzSq#{fCS^>_C%3Zrf!rPryE6bi_V#gdj8IZtM5b$%EFLNh?2z9OR&h1uF(@x8P~ zm(8I(a^Of7#_dYQwz6}M@_qz1WWuSK0EIwJO-&`S5ndSZP|Q8Qci;N9P!X{)0F8@8 zZ$Pai@a51ftBCM}ZP8vXMG&MIe+N()*`Aq@*#%#r+vn0QlS54!0BG3Rb_zz&PeRji z6q~r(!r;pqG6S(%7I4Fo$as^8^`Mb`Vu@e+l`XRaLTW=mhB)ESCh4zFT!aPNxT6g! zEQNjlx$a2@E;a6!4Y0t@QwYq>ls)~e4nfsN#*MjsEI&eQx{uDp3dVIanOsAxxRALO zm$<5Jw|?+K#RELj&y>loH;f9R@Vz3plCmo9*k@SB2ui-SUv`%w(4q9Wy7Qi6=*hCc zVL+qI0X1n_weqN{Y>TzD>~Xg%oMezlh6KUN*$BTLqFfuf{_(msR2g^#Rq1!M9v-{s zuu9)(P8iq+8PPj9_ilxLm@4b-?lyzw?j8(Az~7{G+~)fN?n(cXd6qg*Tp}k@WTf(D zbqq<_C56PTnrfOEXjUyFp7Fe`gD%T2ESskAxz?jSAYRP?7=kF^G(1^8bD?qRdN@U_ zfZ|4yzm4DpS@Km)H2#72kS};0*&GMkA)1R)nAU3n{p$DW7yEFzxlBN@bBF3~YZb`+ z5v`5+yZQ;9(mWdmP#GeS$3df~y3P6c}`V;Y9keGh!{ z>EdE$bvtY0WQWGL=4n?>>TiAuaE`S9gi$h^{nl=)OY`67={hhUt288T|u7jbyPol@~RO8q6Fkl(+D`VPmv9o;+cysEs_(j^d!1df(4B;Rw`QBVTV|1W>D> zfV3F5%anx@0!J+kj6r75r!F)j>)DjBjzx};J$cqkUl&#Y7U$wY`|P@FE6;f5AZg#l5!!1Cyx%+#;sibhh(cx|t``I$ZLdr( z@qR1@h7j`Jp=qV6NTE3NW?^c%9re~xQ6J#PzUg9Y?WJcW08}EXZ9qihm?X?FEPRiP z!GH$8um?73)q*Tn0+uQD&94Vhb>B>XA`8Utjo2l*u$y$sMsP#BLxv5B{UBiu4hzd| z_||Whqm`TE0Y^%JosA+8=&p6reRS7>?(tBp(wfWXnIPhTZ>M%}VnL@G2zlzw)J5gj zJ3s`8dz#kZFX2~o)bS(MjZ*QKdRc<2@hJSccEGHH3@{2|X<<~4(xGqPm;4d<=M$9U zNYGB;(qKkzg#Gh|G0@@p3brV?A@}S)rBf}OI05yIOeE0%{x{e`CvQM`tk}=8E1hiY zP7jd#RU87ccQ#sYHQu|Ol_`_AwHy|(<64AfQgZ5FBU2}I^bHq6>Rw3q&c2|)Fwgzl z`IMh3U2)|#MU8KVjd#;vu8SZX9BW%1t+C$9L@CRV<>&ZZoy{F0w!>>{gz7Q}dY115 zadTt?CzOgrFG0tSu+Q*FMs>THT|Rb+r{So|&0ecFIOKXIlrZt5(@~|)x9bI$DlAB3 z$n^VXqd3>IxdFmPMnu&JdO*bY6>x6rn^opgxXc(7--SH0q#b|;RanRWFzM~@UjmZB z9L}XB%MDPh?f-g6+Fn>vAB8YPz}lxN7ydALWlv09uRrv!@o6SS5F)CDSt$$qzTW{d zMk70RGcAgI1iN;qdV9z;^3*Qx{nh#*U?-c%wwiq@WI;SJT6JVTIyyQyio-JlF`&)O z^^U6HjqCu-f7{2WVOrYo!v2)qxfGp!a*{03pkffg%vAIpgQ$h)JrsR^Xj3tqYtKS`)p*C?(am;(J2 zZ)m1ihnAT>|Lp@Jh786XSZ9qzcpvgfB#Lo+_KNzb;)H)Qct1N6E@ruw_Reu;JCZ1T zB1m+X+OqF7;?d_vCM~}4b33)Mdk;%!W4){W=(RbGwp`hn5@#tG*c9v9=}d_Fp+knf z(E}h=1Jdy0bT!E!58ZH~p5W%^zmH&{gbI)sfgk63B(JRhwIgRE9u_RZjGJ_NKcEf; z!91e40H6oii||zPT-F!1K(%cOPQFUJ(f$F|M^xifL=t}TeS=9KatvuYt$1l4$xBbbU2iP&T7%Pj z=T?noVu#`9LorjfY_zG>W6m;J#=-y{9kH3Yq|;+VWs4IaHDF0AD211BC*=#+_re=! zOGj0K-3Dls4i*<=0Y1OvbbVPm{phP?9=`2g8yIJQNdFk~=$JRSgUm)PyExfV#2IML zZw-{;;|zKiQ%mgHUKhUF@i2@{8;>wWL8tw_?2anF(RBQ1-hdKMRNZZ>w*I_8ij&2` z4#>739VKJlxY>2PXODvCyoE9oe?)L_Xj}EVt%|vZmuyhzRG?iT*$sV1Jl||T|EVAseP%#fXflWcGa;`YKg?2&bFCKuNN9%@ zoh`u5VTV!ZRhwu)rK3lC2-Qrvrx|PvZ)%d&^c_ea+P2gtjQ;gNgY*+_W+#xq3e5h% z8w2Rr1s*L*EoDboT1ZhV*mW%HG#4_Kto~!!d_(m=s)X2;$;68v=km*x6n%&CPv8&` zq5bZ4y4uQM`_RaU={mn5J8c7Y1~G{#!_(QjGKKI1K%T+W#8KL?O9Utor>rbX1poO% z=4lXPAgUxN*}vf>*SNvnD&ya|_wz&KUI(u{tC5#j+qfavn!lC=ff)wsYq!W~0b%R*l{5zh|m7_$CXG_Hfdyd}h`cJ>R?Gk;Syndke zOGl@K-s5E*z3=ZQgV6mP zR^jpht1T4Wp`AMuKE*NqUX>PBi#5ZD^K|nWU4F~Erxho9XVM_vhIPHEaH4}mLJN@+ zBirg44@O>DO@41;jA; zS78ZbQYzKOi^zl|=?@wYgpcrp)cXh`{ITWuy?&{9SQPvQFazA)b26IEYa!)-SAhdp z0MQT>@;S(?zyXKH&ZoRo^hg1du@nvSKsWA8#t3r5)-U()p--hTD6j2e^_IpQq5fje z?mr$FGOF08=B2-EjK+@HbxVE)uq(bl`15L6$}1;=@@D+(#&4xbp{MCKLJ!+Ee{Vm% zY(`~c)Wy`T@r%50rbtEHKI^aR<|Oiwgn*iabyh@&(WNGBE=AbupoCe5jZ%xSJmtnY z2H{!(6o?ykgOj+Y^uG`H`+agR-x3NiyafOyt$;~h!dAG? zX!j#RXtgk;|2+O;T!#p@ZD}EYy}mStqPA1rCf{BZ;g!#m?6`TOLio|5(%1?K4Wr z)k25NB1tE~yzUa)Okn+7=$Qst-80Svxwzk(|4s+BGEy;^Hy94K3j@cC;-qR?bIep*m!F7 zO82XmFR2DKWZl>45S9Z)bDGV!#*vIb8Ca3_@@%6$l7tDc_8l~hc$Xit{+otfCD`a` z9bW4NzZN=?<+tG#&mk-D8z5s7AEWB?^77uo6CBr1E}l7k6~mGcIhM7;KOomK3a`@;Tn9$z|i(5{&T^7UVO^$SJN6q60B8VuFThWdhye z3hYURT=o0GgARiS;OWQ21Fah1;=qtQ$JM|q*szTq6&+oeafr*e`u(%_b7aKD${a)X z#3Bp$z~FE}D6DXzLVL0Xc4h&BDZ1`nUoww`$<~hQY#dRI?m$`TfC}2TwO;+a&Ip2% zii>F<>BKhw09^6!t?3J`bwG&(fG{xiZwcR4=KA6_NKNlx@n>>=ILHEugG5+JbKT|z z9cNEZ4-Ul{vt)7MdO0Mz!U56-2R`C7`)}PDydqff9rG%VM6Em2O320^jOP;lp3%ti zZD{WiVSr1$hTE#S4hc?ajt-i);f4UX&u`xyV!A$jL+Jh9hk1UszC@9LwSX(So@7&* zwk_yXkA&NY;>#*(_d5Uvj^b25`9ni~mUEFtA$&UCf8aQLdXHDRsxY%zkwQ+X5$0GW z*aCcHP}K24!S>~g7vF$|23ZO=h)>!{Z%zh4n}K@vm~;M)4>w~1w^};F`4h7KRJa-k zfe?tbrh?zyw-hG&+=ytJF_U4p%fOPf!#&=H_t_N4XGnLb_&rFY{7BU8lJX|-rlIfy z*n|g|2>){sFhBvgUFAK}iP?oq7Q-wpxqdKLkLqkXootXD)+L7puF!djO)?wu9Nv2QDjvOm2P`Y{;qEZH#{%lH8Zi=J<+XPL2B&2Ziw~p70xr z*_lYy(_fqWme&&~6*d)L^VoloA~QX$r+Qd&hn`c&Ex_(9dB0|=x|Lq(MmiP;lkVAb z&Z47@+8I{7Rz<+cA1sHYq3=SW)Lmg ziprSS0JE3$HjuVvFykTX<>2(fZrNE}v`t6LE;vUo&wx)R7~MZ|9ZL>$5MbFf`n3MC z6IX9U=RLDJyE0Pf&|K8G+_WDbNzH$%{Kv%qX!Zl0r%P>#!l+`Dzyujre3K4$@cZi& zyfRgZq)XmUxSMp3(Cw1>dX;|OsiE-zH@hE6P@W>{8q7_Fmb^iQ}x zi+W`b^hTym~I^65k|Qy>ZjTWSdnJ9ekA)kHxa!Qk61R5A8iQ2I*TGwVX<*x57T z_?bVy2bvZS;`dkU&yN}SWh~?gJLUgR3((vpk!2S)^Mpv_P-J`0$Yf|b;Qq_N^P9xt zAG;bq6My?Nb807?^Vk!1Z_Y~V78InOmlPbZF+Kogs3J_=m$xRW?DPQUBSEZ{n{~^~ zNSvQ$wJvuj$KTXkaB7>t3*-UIli3;iP(py2qd4x$)bL+Img+%8y^T$X0;gjb@4W8_Sg*qU7xKxfQ(-tgRAD8q4^gOeleEvT-9r3>wZ+`D|&+julLSOH(L^h}1R z<}H$01FsivAm$^p!^rB)?|qWHXDjJ#$^d;K8%Rl8L?60zW48Opr{`M%6wQvmNV$JKFZXAU)fjVmyCw;S z{G9>+Gb)h6Q}%Ek9KrD!15*3!%F1DCdtEH8qycRw`w%@}a6!T{OtJ}odUJ87Ib6j3 zvOe``wCFbbs>udqyR^Wz5|E}1cENuDY zt>3|zRq)b!`|(5T&+c<|!rli@(Exv&#tUwOHFYY4SfG|QC*swFIn*my*1a7t9|CD4 z5cfm`=GyHepCvi-91P1y{Xm8kEj*h+Z|$U@7HG*$kctjJSQm)GuC+_iba!_?;CX#W zkzI}LDM522!YUE0uuv6Sb?!2&`CV+Ko^Fn0EW7{8?1i5pjdd@D=UFOt@=B5qS-v#m z+f~wif2|PACi6H$63?N=pEo2`d|5=r)ix|)vWi6i7vs-=WLe2rzerelht3O#18|OY zv3ibCX^-)!+YU**iplDdw(MaO?~wryIJRRzN}qzSs6#iHLr!Rpux+hbw}M-|P@&ls zAgv*x6GB1wtT5LYp_`HE@C6)OfFuz{pd1?aGUbZeYLJlWA zDXE%Mf8*)KGsH*@Zr!Hzulj3tf3yh)>l~&e;oYPIJr!ka6L_Ye#T{>O$j0!h#TXXe zs3hrV&<`|0zuY&V z@Iy(H8d;PIh|X7FPJ>#l_#27cap>R~1*1Fy8*{P_R-!>kZ6!9yaTH5s(S+a6I1^5sP8SI9cG1Cj~+Y{&N3FBB8Xp(|;Wutvq6 z3_lAQ+dB&tNUl*g`dNH_&Oo>6?}&cn<(@;C8yqEZT}H)%*x%(CJIjPl!;4y_ zU$n)(_(B*RPQ#y=d7mA^GK<&c8CkDuq-R5MS_GvKZ#80)%XLa2R1X;1jeOoO0TS;3 z=pt`Zn?>ay8WaS20}T5a!@$V5W|hU7z3-?nZluB^HVK*Y6PF>43I(6%gG#is0NWGp zE{xj?_9wr79R|uZC8G{)Au#vfOA%@&2~Qg3h|TTSO$4C;)M+Ha6WPs*44vNR7J?Hr zdPbDGJQ0$grW`mSeC)FT$`ML)*6tPTIvMs}q+MzU2#ZN6EyBG9Y!%23ZIH<{ebCCo zZh2Pdb(UwuVmykhR7SR6nXYksIR>B`*)WFex^}3UczQlaC~S95>HBTN-5lsaWJN7_ z>))2;Xsu5Gb^xo%d2!#+Kf}bblxvr6|vKQ3jB0f>^)z_8eF0;}8G@PB%+~#d@jB>*d~l5%b8Z zE94<`f>)(%k#Zm&ekL25WUOEP6`jn~wDs(?stwgQHR1Sog)Fsh)2eJ~OnL{cEpa;* zetXtkaFT{f^`J3wCMs{~#0G3fi1wz>DU1c5ZQWeB=w=+_6c*0xOEe&J#A6ioz@;^> zc*PZKVwyn48}-dM;40p?AKx}~^hmQ;cd^qjSaH7O0Y^%Yqu0%jgA$}$3f^g{)+}#qS8S6`sW6#o~mGlRBSDPd{z%HZ*)xSHDu>2q!c6T8EH&(Dr_BT;d(1CS8HHB=G zxcuXUlg|UoA_O|176<`Xz#Pn~Uttd%#{pZv1lSI@VK^m-tW)`=TDJ*US{v9B=B-Pt z0003MQ8cJRX~Dlomj9{BK@G62P4L{bfVUwO7}mGY?aXB*m8?M+N(b;w*xknV8wuTk z4}Te(@PDyZ$hj+iOs)E~Ge_%;B;R`fOak+eE~|C)(9QfBd&wGuD~l&u!GtEWpdjbY zp6=n_@aUa9Sy%89I&!hDk2Fy@#-B}Bq@Z^O9C=C7^;}@;lRR~itPw=XcvF14i`8cC zag&~S>d~9WPxv0q>|@O&O9WmBD|q;sD!^I~KqTPkl|Uba`boYUar^}`qrvn=I8kjM zJh~>PaM+q(dnh%YJmtezn26Jao<_bBkbqzJb3*0m_^18PrI9ufbc1s+Z;0XL=Qr{M z|KSR!CBk_Ml^*HVfINu<4maeFYt&koL

8<<1^lg~Yl%6TV~RFUHSvgbax=fZ`< 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 literal 0 HcmV?d00001 From 27f812f00cb9d122ad3e3b84504ac864cce00d00 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Fri, 15 Mar 2024 21:35:06 -0700 Subject: [PATCH 07/66] Add linkedin list leetcode problems --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index 2829742..21d7fe0 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,21 @@ This repository contains LeetCode resources which are useful during interview pr ## Must-Do Problems (Topic Wise) ### Linked List +- [Reverse Linked List](https://leetcode.com/problems/reverse-linked-list/description/) +- [Linked List Cycle](https://leetcode.com/problems/linked-list-cycle/description/) +- [Merge Two Sorted Lists](https://leetcode.com/problems/merge-two-sorted-lists/description/) +- [Intersection of Two Linked Lists](https://leetcode.com/problems/intersection-of-two-linked-lists/description/) +- [Remove Nth Node From End of List](https://leetcode.com/problems/remove-nth-node-from-end-of-list/description/) +- [Add Two Numbers](https://leetcode.com/problems/add-two-numbers/description/) +- [Copy List with Random Pointer](https://leetcode.com/problems/copy-list-with-random-pointer/description/) +- [Flatten a Multilevel Doubly Linked List](https://leetcode.com/problems/flatten-a-multilevel-doubly-linked-list) +- [Rotate List](https://leetcode.com/problems/rotate-list/description/) +- [Sort List](https://leetcode.com/problems/sort-list/description/) +- [Remove Duplicates from Sorted List II](https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/description/) +- [LRU Cache](https://leetcode.com/problems/lru-cache/description/) +- [Design Browser History](https://leetcode.com/problems/design-browser-history/description/) +- [Merge k Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists/description/) +- [Reverse Nodes in k-Group](https://leetcode.com/problems/reverse-nodes-in-k-group/description/) ### Stacks ### Queues ### Binary Trees From 7fd118ff719cc5c8cbf5f692113f6db351d7faff Mon Sep 17 00:00:00 2001 From: Mohamed Mostafa <54549128+mahmedMostafa@users.noreply.github.com> Date: Sat, 13 Apr 2024 20:58:37 +0200 Subject: [PATCH 08/66] Update README.md :: Add Heap patterns --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 21d7fe0..cd55d4f 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ This repository contains LeetCode resources which are useful during interview pr - [Tree Patterns](https://leetcode.com/discuss/study-guide/937307/Iterative-or-Recursive-or-DFS-and-BFS-Tree-Traversal-or-In-Pre-Post-and-LevelOrder-or-Views) - [Tree Iterative Traversal](https://medium.com/leetcode-patterns/leetcode-pattern-0-iterative-traversals-on-trees-d373568eb0ec) - [Tree Question Pattern](https://leetcode.com/discuss/study-guide/2879240/TREE-QUESTION-PATTERN-2023-oror-TREE-STUDY-GUIDE) +- [Heap Patterns]([https://leetcode.com/discuss/study-guide/655708/Graph-For-Beginners-Problems-or-Pattern-or-Sample-Solutions](https://leetcode.com/discuss/general-discussion/1127238/master-heap-by-solving-23-questions-in-4-patterns-category)) - [Graph Patterns](https://leetcode.com/discuss/study-guide/655708/Graph-For-Beginners-Problems-or-Pattern-or-Sample-Solutions) - [Monotonic Stack Patterns](https://leetcode.com/discuss/study-guide/2347639/A-comprehensive-guide-and-template-for-monotonic-stack-based-problems) - [Bit Manipulation Patterns](https://leetcode.com/discuss/study-guide/4282051/all-types-of-patterns-for-bits-manipulations-and-how-to-use-it) From e7740157aada338e0aa401436c4c857b286a5028 Mon Sep 17 00:00:00 2001 From: Mohamed Mostafa <54549128+mahmedMostafa@users.noreply.github.com> Date: Sat, 13 Apr 2024 20:59:22 +0200 Subject: [PATCH 09/66] Update README.md :: Fix link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cd55d4f..02573b5 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ This repository contains LeetCode resources which are useful during interview pr - [Tree Patterns](https://leetcode.com/discuss/study-guide/937307/Iterative-or-Recursive-or-DFS-and-BFS-Tree-Traversal-or-In-Pre-Post-and-LevelOrder-or-Views) - [Tree Iterative Traversal](https://medium.com/leetcode-patterns/leetcode-pattern-0-iterative-traversals-on-trees-d373568eb0ec) - [Tree Question Pattern](https://leetcode.com/discuss/study-guide/2879240/TREE-QUESTION-PATTERN-2023-oror-TREE-STUDY-GUIDE) -- [Heap Patterns]([https://leetcode.com/discuss/study-guide/655708/Graph-For-Beginners-Problems-or-Pattern-or-Sample-Solutions](https://leetcode.com/discuss/general-discussion/1127238/master-heap-by-solving-23-questions-in-4-patterns-category)) +- [Heap Patterns](https://leetcode.com/discuss/study-guide/655708/Graph-For-Beginners-Problems-or-Pattern-or-Sample-Solutions](https://leetcode.com/discuss/general-discussion/1127238/master-heap-by-solving-23-questions-in-4-patterns-category)) - [Graph Patterns](https://leetcode.com/discuss/study-guide/655708/Graph-For-Beginners-Problems-or-Pattern-or-Sample-Solutions) - [Monotonic Stack Patterns](https://leetcode.com/discuss/study-guide/2347639/A-comprehensive-guide-and-template-for-monotonic-stack-based-problems) - [Bit Manipulation Patterns](https://leetcode.com/discuss/study-guide/4282051/all-types-of-patterns-for-bits-manipulations-and-how-to-use-it) From 69d4caf615dbc8cddfcb3c379d7ec5242669e348 Mon Sep 17 00:00:00 2001 From: Mohamed Mostafa <54549128+mahmedMostafa@users.noreply.github.com> Date: Sat, 13 Apr 2024 21:00:10 +0200 Subject: [PATCH 10/66] Update README.md :: Fix link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 02573b5..e52096c 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ This repository contains LeetCode resources which are useful during interview pr - [Tree Patterns](https://leetcode.com/discuss/study-guide/937307/Iterative-or-Recursive-or-DFS-and-BFS-Tree-Traversal-or-In-Pre-Post-and-LevelOrder-or-Views) - [Tree Iterative Traversal](https://medium.com/leetcode-patterns/leetcode-pattern-0-iterative-traversals-on-trees-d373568eb0ec) - [Tree Question Pattern](https://leetcode.com/discuss/study-guide/2879240/TREE-QUESTION-PATTERN-2023-oror-TREE-STUDY-GUIDE) -- [Heap Patterns](https://leetcode.com/discuss/study-guide/655708/Graph-For-Beginners-Problems-or-Pattern-or-Sample-Solutions](https://leetcode.com/discuss/general-discussion/1127238/master-heap-by-solving-23-questions-in-4-patterns-category)) +- [Heap Patterns](https://leetcode.com/discuss/general-discussion/1127238/master-heap-by-solving-23-questions-in-4-patterns-category) - [Graph Patterns](https://leetcode.com/discuss/study-guide/655708/Graph-For-Beginners-Problems-or-Pattern-or-Sample-Solutions) - [Monotonic Stack Patterns](https://leetcode.com/discuss/study-guide/2347639/A-comprehensive-guide-and-template-for-monotonic-stack-based-problems) - [Bit Manipulation Patterns](https://leetcode.com/discuss/study-guide/4282051/all-types-of-patterns-for-bits-manipulations-and-how-to-use-it) From 86d205a8240058ad91c24edd5343e3a8be2e2792 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Thu, 25 Apr 2024 09:17:52 -0700 Subject: [PATCH 11/66] add time complexity article --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e52096c..c1c29d8 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ This repository contains LeetCode resources which are useful during interview preparation. ## Fundamental Concepts +- [Time Complexity](https://www.freecodecamp.org/news/big-o-cheat-sheet-time-complexity-chart/) - [Linked List](https://leetcode.com/discuss/study-guide/1800120/become-master-in-linked-list) - [Queues](https://medium.com/basecs/to-queue-or-not-to-queue-2653bcde5b04) - [Stacks](https://medium.com/basecs/stacks-and-overflows-dbcf7854dc67) From a78c9f1d94336cbeb1dd3fc58ddbe4132eb9747c Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Thu, 25 Apr 2024 20:17:34 -0700 Subject: [PATCH 12/66] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c1c29d8..9a2cfd2 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@

LinkedIn | YouTube | X | Newsletter

-This repository contains LeetCode resources which are useful during interview preparation. +Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and prepare for Coding interviews. ## Fundamental Concepts - [Time Complexity](https://www.freecodecamp.org/news/big-o-cheat-sheet-time-complexity-chart/) From 447e4561724dd2619d492ec6f72dcea40371491b Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Fri, 3 May 2024 01:48:59 -0700 Subject: [PATCH 13/66] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 9a2cfd2..4bdfbe0 100644 --- a/README.md +++ b/README.md @@ -123,3 +123,6 @@ Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and pre Your contributions are most welcome! + +--- +### If you found this repository helpful, you can [buy me a coffee](https://buymeacoffee.com/ashishps). From 45485ee8292cb80955ccef150f075ea7bf313c19 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Fri, 3 May 2024 01:50:58 -0700 Subject: [PATCH 14/66] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4bdfbe0..c2f9157 100644 --- a/README.md +++ b/README.md @@ -125,4 +125,4 @@ Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and pre Your contributions are most welcome! --- -### If you found this repository helpful, you can [buy me a coffee](https://buymeacoffee.com/ashishps). +### If you found this repository helpful, you can show your support by [buying me a coffee](https://buymeacoffee.com/ashishps). From b9cf7120ecef3eac8d1f1d30ede7dc0359188658 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Sun, 5 May 2024 23:01:05 -0700 Subject: [PATCH 15/66] Add Big-O Cheat sheet --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c2f9157..e97caac 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and pre ## Fundamental Concepts - [Time Complexity](https://www.freecodecamp.org/news/big-o-cheat-sheet-time-complexity-chart/) +- [Big-O Cheat Sheet](https://www.bigocheatsheet.com/) - [Linked List](https://leetcode.com/discuss/study-guide/1800120/become-master-in-linked-list) - [Queues](https://medium.com/basecs/to-queue-or-not-to-queue-2653bcde5b04) - [Stacks](https://medium.com/basecs/stacks-and-overflows-dbcf7854dc67) From c24ba67d4bc8b0c186121fbd6eecb64555c7764c Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Tue, 7 May 2024 21:54:56 -0700 Subject: [PATCH 16/66] Update README.md --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index e97caac..819f942 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,3 @@ Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and pre Your contributions are most welcome! - ---- -### If you found this repository helpful, you can show your support by [buying me a coffee](https://buymeacoffee.com/ashishps). From c90d78aa7c4831e209f4266ce78d519372dd3a4b Mon Sep 17 00:00:00 2001 From: Jaroslaw Weber Date: Sat, 18 May 2024 23:59:39 +0900 Subject: [PATCH 17/66] add visualization tool --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 819f942..0fc2898 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,9 @@ Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and pre - [Coursera - Algorithms, Part I](https://www.coursera.org/learn/algorithms-part1) - [Coursera - Algorithms, Part 2](https://www.coursera.org/learn/algorithms-part2) +## Visualization +- [Algo-lens: Visualize leetcode problems](https://github.com/jaroslaw-weber/algo-lens) + ## Must-Do Problems (Topic Wise) ### Linked List - [Reverse Linked List](https://leetcode.com/problems/reverse-linked-list/description/) From 9f58c32ba79d7f398c2cfe942573b9d91f67fefc Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Tue, 28 May 2024 18:32:45 -0700 Subject: [PATCH 18/66] Update README.md --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index 819f942..50212bb 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,6 @@ Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and pre - [LeetCode VS Code Extension](https://marketplace.visualstudio.com/items?itemName=LeetCode.vscode-leetcode): Solve LeetCode problems in VS Code. ## Curated Problems -- [Blind 75](https://neetcode.io/practice) - [Leetcode Top 100 Liked](https://leetcode.com/studyplan/top-100-liked/) - [Leetcode Top Interview 150](https://leetcode.com/studyplan/top-interview-150/) - [Leetcode 75](https://leetcode.com/studyplan/leetcode-75/) @@ -82,8 +81,6 @@ Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and pre - [Design Browser History](https://leetcode.com/problems/design-browser-history/description/) - [Merge k Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists/description/) - [Reverse Nodes in k-Group](https://leetcode.com/problems/reverse-nodes-in-k-group/description/) -### Stacks -### Queues ### Binary Trees - [Invert Binary Tree](https://leetcode.com/problems/invert-binary-tree/description/) - [Convert Sorted Array to Binary Search Tree](https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/description/) From 5248fc070ab799d1b8105327b83d147026fe9809 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Fri, 7 Jun 2024 04:10:04 -0700 Subject: [PATCH 19/66] Update newsletter link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 50212bb..e485dc7 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@

- LinkedIn | YouTube | X | Newsletter + LinkedIn | YouTube | X | Newsletter

Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and prepare for Coding interviews. From c0530f11df3fbd54e1e3579938c9bc33a9866c59 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Sat, 15 Jun 2024 00:16:50 -0700 Subject: [PATCH 20/66] Add dummy node technique for linked lists --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e485dc7..9a11b31 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and pre - [Time Complexity](https://www.freecodecamp.org/news/big-o-cheat-sheet-time-complexity-chart/) - [Big-O Cheat Sheet](https://www.bigocheatsheet.com/) - [Linked List](https://leetcode.com/discuss/study-guide/1800120/become-master-in-linked-list) + - [Dummy Node Technique](https://blog.algomaster.io/p/5d7a1368-7a0c-461a-93a9-732333ceb2a8) - [Queues](https://medium.com/basecs/to-queue-or-not-to-queue-2653bcde5b04) - [Stacks](https://medium.com/basecs/stacks-and-overflows-dbcf7854dc67) - [Hash Tables](https://medium.com/basecs/taking-hash-tables-off-the-shelf-139cbf4752f0) From 7e0cd645ea4dd9483a54d4f20582cf9634d3e254 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Sat, 15 Jun 2024 11:28:41 -0700 Subject: [PATCH 21/66] Add backtracking problems --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index 9a11b31..1d33790 100644 --- a/README.md +++ b/README.md @@ -108,6 +108,24 @@ Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and pre - [Binary Tree Cameras](https://leetcode.com/problems/binary-tree-cameras/description/) - [Binary Tree Maximum Path Sum](https://leetcode.com/problems/binary-tree-maximum-path-sum/description/) - [Maximum Sum BST in Binary Tree](https://leetcode.com/problems/maximum-sum-bst-in-binary-tree/description/) +### Stacks +### Queues +### Hash Tables +### Priority Queues +### Backtracking +- [Permutations](https://leetcode.com/problems/permutations/description/) +- [Subsets](https://leetcode.com/problems/subsets/description/) +- [Generate Parentheses](https://leetcode.com/problems/generate-parentheses/description/) +- [Combination Sum](https://leetcode.com/problems/combination-sum/description/) +- [Palindrome Partitioning](https://leetcode.com/problems/palindrome-partitioning/description/) +- [Letter Combinations of a Phone Number](https://leetcode.com/problems/letter-combinations-of-a-phone-number/description/) +- [Unique Binary Search Trees II](https://leetcode.com/problems/unique-binary-search-trees-ii/description/) +- [Partition to K Equal Sum Subsets](https://leetcode.com/problems/partition-to-k-equal-sum-subsets/description/) +- [N-Queens II](https://leetcode.com/problems/n-queens-ii/description/) +- [Sudoku Solver](https://leetcode.com/problems/sudoku-solver/description/) +### Graphs +### Binary Search +### Dynamic Programming ### Tries - [Implement Trie (Prefix Tree)](https://leetcode.com/problems/implement-trie-prefix-tree/description/) - [Longest Common Prefix](https://leetcode.com/problems/longest-common-prefix/description/) From 0a667b20f77e7b20458e9722b956828739d85c81 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Sat, 15 Jun 2024 12:17:30 -0700 Subject: [PATCH 22/66] add algorithmic complexity article --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1d33790..494bcc0 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and prepare for Coding interviews. ## Fundamental Concepts -- [Time Complexity](https://www.freecodecamp.org/news/big-o-cheat-sheet-time-complexity-chart/) +- [Algorithmic Complexity](https://blog.algomaster.io/p/57bd4963-462f-4294-a972-4012691fc729) - [Big-O Cheat Sheet](https://www.bigocheatsheet.com/) - [Linked List](https://leetcode.com/discuss/study-guide/1800120/become-master-in-linked-list) - [Dummy Node Technique](https://blog.algomaster.io/p/5d7a1368-7a0c-461a-93a9-732333ceb2a8) From 69b27e966172b1efc09e192ec0af9a67e9e025e0 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Sat, 15 Jun 2024 12:53:32 -0700 Subject: [PATCH 23/66] Add YT Playlists --- README.md | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 99d0a54..f2797d6 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and pre ## Fundamental Concepts - [Algorithmic Complexity](https://blog.algomaster.io/p/57bd4963-462f-4294-a972-4012691fc729) - [Big-O Cheat Sheet](https://www.bigocheatsheet.com/) +- [Sorting Algorithms](https://medium.com/jl-codes/understanding-sorting-algorithms-af6222995c8) - [Linked List](https://leetcode.com/discuss/study-guide/1800120/become-master-in-linked-list) - [Dummy Node Technique](https://blog.algomaster.io/p/5d7a1368-7a0c-461a-93a9-732333ceb2a8) - [Queues](https://medium.com/basecs/to-queue-or-not-to-queue-2653bcde5b04) @@ -16,14 +17,16 @@ Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and pre - [Hash Tables](https://medium.com/basecs/taking-hash-tables-off-the-shelf-139cbf4752f0) - [Heaps](https://medium.com/basecs/learning-to-love-heaps-cef2b273a238) - [Recursion](https://leetcode.com/discuss/study-guide/1733447/become-master-in-recursion) +- [Backtracking](https://medium.com/algorithms-and-leetcode/backtracking-e001561b9f28) - [Trees](https://leetcode.com/discuss/study-guide/1820334/Become-Master-in-Tree) - [Tries](https://medium.com/basecs/trying-to-understand-tries-3ec6bede0014) - [Binary Search](https://leetcode.com/discuss/study-guide/786126/Python-Powerful-Ultimate-Binary-Search-Template.-Solved-many-problems) +- [Greedy Algorithm](https://www.freecodecamp.org/news/greedy-algorithms/) - [Dynamic Programming](https://medium.com/basecs/less-repetition-more-dynamic-programming-43d29830a630) - [Graph Theory](https://medium.com/basecs/a-gentle-introduction-to-graph-theory-77969829ead8) - [DFS Traversal](https://medium.com/basecs/deep-dive-through-a-graph-dfs-traversal-8177df5d0f13) - [BFS Traversal](https://medium.com/basecs/going-broad-in-a-graph-bfs-traversal-959bd1a09255) -- [Dijkstra Algorithm](https://medium.com/basecs/finding-the-shortest-path-with-a-little-help-from-dijkstra-613149fbdc8e) +- [Dijkstra Algorithm](https://leetcode.com/discuss/study-guide/1059477/A-guide-to-Dijkstra's-Algorithm) ## Patterns - [14 Coding Interview Patterns](https://hackernoon.com/14-patterns-to-ace-any-coding-interview-question-c5bb3357f6ed) @@ -45,6 +48,24 @@ Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and pre - [DFS + BFS Patterns (2)](https://medium.com/leetcode-patterns/leetcode-pattern-2-dfs-bfs-25-of-the-problems-part-2-a5b269597f52) - [Stock Series Patterns](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/solutions/108870/most-consistent-ways-of-dealing-with-the-series-of-stock-problems/) +## YouTube Playlist +- [Abdul Bari's Algorithms Playlist](https://www.youtube.com/playlist?list=PLDN4rrl48XKpZkf03iYFl-O29szjTrs_O) +- [William Fiset's Data Structure Playlist](https://www.youtube.com/playlist?list=PLDV1Zeh2NRsB6SWUrDFW2RmDotAfPbeHu) +- [William Fiset's Graphs Playlist](https://www.youtube.com/playlist?list=PLDV1Zeh2NRsDGO4--qE8yH72HFL1Km93P) +- [Tushar Roy's Dynamic Programming Playlist](https://www.youtube.com/playlist?list=PLrmLmBdmIlpsHaNTPP_jHHDx_os9ItYXr) + +## Courses +- [Coursera - Algorithms, Part I](https://www.coursera.org/learn/algorithms-part1) +- [Coursera - Algorithms, Part 2](https://www.coursera.org/learn/algorithms-part2) + +## Books +- [Data Structures And Algorithms Made Easy](https://www.amazon.com/Data-Structures-Algorithms-Made-Easy-ebook/dp/B0CBW278NC/) +- [Cracking the Coding Interview](https://www.amazon.com/Cracking-Coding-Interview-Programming-Questions/dp/0984782850/) + +## Visualization +- [VisuAlgo](https://visualgo.net/en) +- [Algo-lens: Visualize leetcode problems](https://github.com/jaroslaw-weber/algo-lens) + ## LeetCode Extensions - [LeetCode Timer](https://chromewebstore.google.com/detail/leetcode-timer/gfkgelnlcnomnahkfmhemgpahgmibofd): Easily time your leetcode practise sessions with automatic time setting based on difficulty. - [LeetCode Video Solutions](https://chromewebstore.google.com/detail/leetcode-video-solutions/ilnmgkahgjdpkoliooildngldmilhelm): Watch free LeetCode video ▶ solutions on the problem page itself. @@ -57,17 +78,6 @@ Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and pre - [Leetcode Top Interview 150](https://leetcode.com/studyplan/top-interview-150/) - [Leetcode 75](https://leetcode.com/studyplan/leetcode-75/) -## Books -- [Data Structures And Algorithms Made Easy](https://www.amazon.com/Data-Structures-Algorithms-Made-Easy-ebook/dp/B0CBW278NC/) -- [Cracking the Coding Interview](https://www.amazon.com/Cracking-Coding-Interview-Programming-Questions/dp/0984782850/) - -## Courses -- [Coursera - Algorithms, Part I](https://www.coursera.org/learn/algorithms-part1) -- [Coursera - Algorithms, Part 2](https://www.coursera.org/learn/algorithms-part2) - -## Visualization -- [Algo-lens: Visualize leetcode problems](https://github.com/jaroslaw-weber/algo-lens) - ## Must-Do Problems (Topic Wise) ### Linked List - [Reverse Linked List](https://leetcode.com/problems/reverse-linked-list/description/) @@ -111,10 +121,6 @@ Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and pre - [Binary Tree Cameras](https://leetcode.com/problems/binary-tree-cameras/description/) - [Binary Tree Maximum Path Sum](https://leetcode.com/problems/binary-tree-maximum-path-sum/description/) - [Maximum Sum BST in Binary Tree](https://leetcode.com/problems/maximum-sum-bst-in-binary-tree/description/) -### Stacks -### Queues -### Hash Tables -### Priority Queues ### Backtracking - [Permutations](https://leetcode.com/problems/permutations/description/) - [Subsets](https://leetcode.com/problems/subsets/description/) @@ -126,9 +132,6 @@ Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and pre - [Partition to K Equal Sum Subsets](https://leetcode.com/problems/partition-to-k-equal-sum-subsets/description/) - [N-Queens II](https://leetcode.com/problems/n-queens-ii/description/) - [Sudoku Solver](https://leetcode.com/problems/sudoku-solver/description/) -### Graphs -### Binary Search -### Dynamic Programming ### Tries - [Implement Trie (Prefix Tree)](https://leetcode.com/problems/implement-trie-prefix-tree/description/) - [Longest Common Prefix](https://leetcode.com/problems/longest-common-prefix/description/) From 98e2d8f027429ced0b5a8d15249b4ec2a73314a9 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Sun, 16 Jun 2024 00:14:18 -0700 Subject: [PATCH 24/66] Add additional patterns --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f2797d6..5016068 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,8 @@ Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and pre ## Patterns - [14 Coding Interview Patterns](https://hackernoon.com/14-patterns-to-ace-any-coding-interview-question-c5bb3357f6ed) +- [Fast and Slow Pointers Pattern](https://medium.com/@arifimran5/fast-and-slow-pointer-pattern-in-linked-list-43647869ac99) +- [Prefix Sum Pattern](https://leetcodethehardway.com/tutorials/basic-topics/prefix-sum) - [Sliding Window patterns](https://leetcode.com/problems/frequency-of-the-most-frequent-element/solutions/1175088/C++-Maximum-Sliding-Window-Cheatsheet-Template/) - [Two Pointers Patterns](https://leetcode.com/discuss/study-guide/1688903/Solved-all-two-pointers-problems-in-100-days) - [Substring Problem Patterns](https://leetcode.com/problems/minimum-window-substring/solutions/26808/Here-is-a-10-line-template-that-can-solve-most-'substring'-problems/) From e10035fdb1e35c494a5a53db4fa51a15e2f7ace9 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Sun, 16 Jun 2024 00:39:55 -0700 Subject: [PATCH 25/66] Add union find and minimum spanning tree articles --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 5016068..1065c89 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,9 @@ Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and pre - [Graph Theory](https://medium.com/basecs/a-gentle-introduction-to-graph-theory-77969829ead8) - [DFS Traversal](https://medium.com/basecs/deep-dive-through-a-graph-dfs-traversal-8177df5d0f13) - [BFS Traversal](https://medium.com/basecs/going-broad-in-a-graph-bfs-traversal-959bd1a09255) +- [Union-Find](https://leetcode.com/discuss/general-discussion/1072418/Disjoint-Set-Union-(DSU)Union-Find-A-Complete-Guide) - [Dijkstra Algorithm](https://leetcode.com/discuss/study-guide/1059477/A-guide-to-Dijkstra's-Algorithm) +- [Minimum Spanning Tree](https://www.hackerearth.com/practice/algorithms/graphs/minimum-spanning-tree/tutorial/) ## Patterns - [14 Coding Interview Patterns](https://hackernoon.com/14-patterns-to-ace-any-coding-interview-question-c5bb3357f6ed) From 389babd9d2dcfa925d7b47da46056b96fa48247e Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Sun, 16 Jun 2024 10:21:54 -0700 Subject: [PATCH 26/66] Add tips --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 1065c89..1ed7d75 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,10 @@

Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and prepare for Coding interviews. +## Tips +- [How to Start LeetCode](https://www.youtube.com/watch?v=Nx4bvwU0DqE) +- [How I Mastered DSA](https://blog.algomaster.io/p/how-i-mastered-data-structures-and-algorithms) + ## Fundamental Concepts - [Algorithmic Complexity](https://blog.algomaster.io/p/57bd4963-462f-4294-a972-4012691fc729) - [Big-O Cheat Sheet](https://www.bigocheatsheet.com/) From a8a91bd95baffc5b8d85709fae72c26219767f9d Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Wed, 3 Jul 2024 11:48:29 -0700 Subject: [PATCH 27/66] Update README.md --- README.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 1ed7d75..f7cf1c3 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,11 @@

Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and prepare for Coding interviews. -## Tips +## 💡 Tips - [How to Start LeetCode](https://www.youtube.com/watch?v=Nx4bvwU0DqE) - [How I Mastered DSA](https://blog.algomaster.io/p/how-i-mastered-data-structures-and-algorithms) -## Fundamental Concepts +## 📌 Fundamental Concepts - [Algorithmic Complexity](https://blog.algomaster.io/p/57bd4963-462f-4294-a972-4012691fc729) - [Big-O Cheat Sheet](https://www.bigocheatsheet.com/) - [Sorting Algorithms](https://medium.com/jl-codes/understanding-sorting-algorithms-af6222995c8) @@ -34,7 +34,7 @@ Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and pre - [Dijkstra Algorithm](https://leetcode.com/discuss/study-guide/1059477/A-guide-to-Dijkstra's-Algorithm) - [Minimum Spanning Tree](https://www.hackerearth.com/practice/algorithms/graphs/minimum-spanning-tree/tutorial/) -## Patterns +## 🚀 Patterns - [14 Coding Interview Patterns](https://hackernoon.com/14-patterns-to-ace-any-coding-interview-question-c5bb3357f6ed) - [Fast and Slow Pointers Pattern](https://medium.com/@arifimran5/fast-and-slow-pointer-pattern-in-linked-list-43647869ac99) - [Prefix Sum Pattern](https://leetcodethehardway.com/tutorials/basic-topics/prefix-sum) @@ -56,21 +56,22 @@ Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and pre - [DFS + BFS Patterns (2)](https://medium.com/leetcode-patterns/leetcode-pattern-2-dfs-bfs-25-of-the-problems-part-2-a5b269597f52) - [Stock Series Patterns](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/solutions/108870/most-consistent-ways-of-dealing-with-the-series-of-stock-problems/) -## YouTube Playlist +## 📺 YouTube Playlist - [Abdul Bari's Algorithms Playlist](https://www.youtube.com/playlist?list=PLDN4rrl48XKpZkf03iYFl-O29szjTrs_O) - [William Fiset's Data Structure Playlist](https://www.youtube.com/playlist?list=PLDV1Zeh2NRsB6SWUrDFW2RmDotAfPbeHu) - [William Fiset's Graphs Playlist](https://www.youtube.com/playlist?list=PLDV1Zeh2NRsDGO4--qE8yH72HFL1Km93P) - [Tushar Roy's Dynamic Programming Playlist](https://www.youtube.com/playlist?list=PLrmLmBdmIlpsHaNTPP_jHHDx_os9ItYXr) -## Courses +## 📇 Courses - [Coursera - Algorithms, Part I](https://www.coursera.org/learn/algorithms-part1) - [Coursera - Algorithms, Part 2](https://www.coursera.org/learn/algorithms-part2) +- [Grokking Coding Interview Patterns](https://www.educative.io/courses/grokking-coding-interview-patterns-java?aff=BZyO) -## Books +## 📚 Books - [Data Structures And Algorithms Made Easy](https://www.amazon.com/Data-Structures-Algorithms-Made-Easy-ebook/dp/B0CBW278NC/) - [Cracking the Coding Interview](https://www.amazon.com/Cracking-Coding-Interview-Programming-Questions/dp/0984782850/) -## Visualization +## 🔎 Visualization - [VisuAlgo](https://visualgo.net/en) - [Algo-lens: Visualize leetcode problems](https://github.com/jaroslaw-weber/algo-lens) @@ -81,12 +82,12 @@ Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and pre - [LeetHub v2](https://chromewebstore.google.com/detail/leethub-v2/mhanfgfagplhgemhjfeolkkdidbakocm?hl=en): Automatically integrate your Leetcode & GeeksforGeeks submissions to GitHub. - [LeetCode VS Code Extension](https://marketplace.visualstudio.com/items?itemName=LeetCode.vscode-leetcode): Solve LeetCode problems in VS Code. -## Curated Problems +## ✅ Curated Problems - [Leetcode Top 100 Liked](https://leetcode.com/studyplan/top-100-liked/) - [Leetcode Top Interview 150](https://leetcode.com/studyplan/top-interview-150/) - [Leetcode 75](https://leetcode.com/studyplan/leetcode-75/) -## Must-Do Problems (Topic Wise) +## 💻 Must-Do Problems (Topic Wise) ### Linked List - [Reverse Linked List](https://leetcode.com/problems/reverse-linked-list/description/) - [Linked List Cycle](https://leetcode.com/problems/linked-list-cycle/description/) From a673f841d419b90d76ec721234a5507c8d82bd12 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Wed, 3 Jul 2024 11:52:51 -0700 Subject: [PATCH 28/66] Add icons --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f7cf1c3..4c9ffd9 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and pre - [VisuAlgo](https://visualgo.net/en) - [Algo-lens: Visualize leetcode problems](https://github.com/jaroslaw-weber/algo-lens) -## LeetCode Extensions +## 📎 LeetCode Extensions - [LeetCode Timer](https://chromewebstore.google.com/detail/leetcode-timer/gfkgelnlcnomnahkfmhemgpahgmibofd): Easily time your leetcode practise sessions with automatic time setting based on difficulty. - [LeetCode Video Solutions](https://chromewebstore.google.com/detail/leetcode-video-solutions/ilnmgkahgjdpkoliooildngldmilhelm): Watch free LeetCode video ▶ solutions on the problem page itself. - [LeetCode Format](https://chromewebstore.google.com/detail/leetcode-format/imogghebhifnnlgogigikjecilkicfpp): Adds Format code button on leetcode to format the code using Prettier code formatter. From b0549aac0ccee5f1e3589d48d64803b280fb96c1 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Wed, 3 Jul 2024 12:11:07 -0700 Subject: [PATCH 29/66] Update header --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4c9ffd9..70fdf62 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,10 @@

- LinkedIn | YouTube | X | Newsletter + Join Free Newsletter

-Awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and prepare for Coding interviews. + +This repository contains awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and prepare for Coding interviews. ## 💡 Tips - [How to Start LeetCode](https://www.youtube.com/watch?v=Nx4bvwU0DqE) From 7bc98601ebeca9add35e0dff1919f3ce77b216b4 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Fri, 5 Jul 2024 00:55:30 -0700 Subject: [PATCH 30/66] Update grokking coding patterns link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 70fdf62..2c5b743 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ This repository contains awesome LeetCode resources to learn Data Structures and ## 📇 Courses - [Coursera - Algorithms, Part I](https://www.coursera.org/learn/algorithms-part1) - [Coursera - Algorithms, Part 2](https://www.coursera.org/learn/algorithms-part2) -- [Grokking Coding Interview Patterns](https://www.educative.io/courses/grokking-coding-interview-patterns-java?aff=BZyO) +- [Grokking the Coding Interview: Patterns for Coding Questions](https://www.designgurus.io/course/grokking-the-coding-interview/?aff=mopp8k) ## 📚 Books - [Data Structures And Algorithms Made Easy](https://www.amazon.com/Data-Structures-Algorithms-Made-Easy-ebook/dp/B0CBW278NC/) From 1875c98c877b5ac98f470f5326bc2645da10cf92 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Tue, 16 Jul 2024 02:12:02 -0700 Subject: [PATCH 31/66] Add bit manipulation article --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2c5b743..34e7ac9 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ This repository contains awesome LeetCode resources to learn Data Structures and ## 📌 Fundamental Concepts - [Algorithmic Complexity](https://blog.algomaster.io/p/57bd4963-462f-4294-a972-4012691fc729) - [Big-O Cheat Sheet](https://www.bigocheatsheet.com/) +- [Bit Manipulation Techniques](https://blog.algomaster.io/p/c650df76-f978-46ee-a572-eb13c354905d) - [Sorting Algorithms](https://medium.com/jl-codes/understanding-sorting-algorithms-af6222995c8) - [Linked List](https://leetcode.com/discuss/study-guide/1800120/become-master-in-linked-list) - [Dummy Node Technique](https://blog.algomaster.io/p/5d7a1368-7a0c-461a-93a9-732333ceb2a8) From 15f88dfe494048d0abf455d105691ef692cc3c2f Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Sat, 20 Jul 2024 21:38:39 -0700 Subject: [PATCH 32/66] Update leetcode patterns articles --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 34e7ac9..15e1acf 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ This repository contains awesome LeetCode resources to learn Data Structures and - [Minimum Spanning Tree](https://www.hackerearth.com/practice/algorithms/graphs/minimum-spanning-tree/tutorial/) ## 🚀 Patterns -- [14 Coding Interview Patterns](https://hackernoon.com/14-patterns-to-ace-any-coding-interview-question-c5bb3357f6ed) +- [15 Leetcode Patterns](https://blog.algomaster.io/p/15-leetcode-patterns) - [Fast and Slow Pointers Pattern](https://medium.com/@arifimran5/fast-and-slow-pointer-pattern-in-linked-list-43647869ac99) - [Prefix Sum Pattern](https://leetcodethehardway.com/tutorials/basic-topics/prefix-sum) - [Sliding Window patterns](https://leetcode.com/problems/frequency-of-the-most-frequent-element/solutions/1175088/C++-Maximum-Sliding-Window-Cheatsheet-Template/) From 355fd2b0e19bd7cd09e2fe0f7b2bdf9c64940f3c Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Mon, 22 Jul 2024 15:35:33 -0700 Subject: [PATCH 33/66] Add prefix sum pattern --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 15e1acf..a1f039f 100644 --- a/README.md +++ b/README.md @@ -38,8 +38,8 @@ This repository contains awesome LeetCode resources to learn Data Structures and ## 🚀 Patterns - [15 Leetcode Patterns](https://blog.algomaster.io/p/15-leetcode-patterns) +- [Prefix Sum Pattern](https://blog.algomaster.io/p/f96dd3de-c89c-428e-a88d-b1f751a42a57) - [Fast and Slow Pointers Pattern](https://medium.com/@arifimran5/fast-and-slow-pointer-pattern-in-linked-list-43647869ac99) -- [Prefix Sum Pattern](https://leetcodethehardway.com/tutorials/basic-topics/prefix-sum) - [Sliding Window patterns](https://leetcode.com/problems/frequency-of-the-most-frequent-element/solutions/1175088/C++-Maximum-Sliding-Window-Cheatsheet-Template/) - [Two Pointers Patterns](https://leetcode.com/discuss/study-guide/1688903/Solved-all-two-pointers-problems-in-100-days) - [Substring Problem Patterns](https://leetcode.com/problems/minimum-window-substring/solutions/26808/Here-is-a-10-line-template-that-can-solve-most-'substring'-problems/) From bd9a9e622520a7dd672dab2344ae2a65c928d764 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Mon, 22 Jul 2024 20:01:39 -0700 Subject: [PATCH 34/66] separate out leetcode articles --- README.md | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index a1f039f..f9fd163 100644 --- a/README.md +++ b/README.md @@ -40,22 +40,24 @@ This repository contains awesome LeetCode resources to learn Data Structures and - [15 Leetcode Patterns](https://blog.algomaster.io/p/15-leetcode-patterns) - [Prefix Sum Pattern](https://blog.algomaster.io/p/f96dd3de-c89c-428e-a88d-b1f751a42a57) - [Fast and Slow Pointers Pattern](https://medium.com/@arifimran5/fast-and-slow-pointer-pattern-in-linked-list-43647869ac99) -- [Sliding Window patterns](https://leetcode.com/problems/frequency-of-the-most-frequent-element/solutions/1175088/C++-Maximum-Sliding-Window-Cheatsheet-Template/) -- [Two Pointers Patterns](https://leetcode.com/discuss/study-guide/1688903/Solved-all-two-pointers-problems-in-100-days) -- [Substring Problem Patterns](https://leetcode.com/problems/minimum-window-substring/solutions/26808/Here-is-a-10-line-template-that-can-solve-most-'substring'-problems/) -- [Dynamic Programming Patterns](https://leetcode.com/discuss/study-guide/458695/Dynamic-Programming-Patterns) -- [Binary Search Patterns](https://leetcode.com/discuss/study-guide/786126/Python-Powerful-Ultimate-Binary-Search-Template.-Solved-many-problems) -- [Backtracking Patterns](https://leetcode.com/problems/permutations/solutions/18239/A-general-approach-to-backtracking-questions-in-Java-(Subsets-Permutations-Combination-Sum-Palindrome-Partioning)/) - [Tree Patterns](https://leetcode.com/discuss/study-guide/937307/Iterative-or-Recursive-or-DFS-and-BFS-Tree-Traversal-or-In-Pre-Post-and-LevelOrder-or-Views) - [Tree Iterative Traversal](https://medium.com/leetcode-patterns/leetcode-pattern-0-iterative-traversals-on-trees-d373568eb0ec) - [Tree Question Pattern](https://leetcode.com/discuss/study-guide/2879240/TREE-QUESTION-PATTERN-2023-oror-TREE-STUDY-GUIDE) -- [Heap Patterns](https://leetcode.com/discuss/general-discussion/1127238/master-heap-by-solving-23-questions-in-4-patterns-category) - [Graph Patterns](https://leetcode.com/discuss/study-guide/655708/Graph-For-Beginners-Problems-or-Pattern-or-Sample-Solutions) -- [Monotonic Stack Patterns](https://leetcode.com/discuss/study-guide/2347639/A-comprehensive-guide-and-template-for-monotonic-stack-based-problems) -- [Bit Manipulation Patterns](https://leetcode.com/discuss/study-guide/4282051/all-types-of-patterns-for-bits-manipulations-and-how-to-use-it) -- [String Question Patterns](https://leetcode.com/discuss/study-guide/2001789/Collections-of-Important-String-questions-Pattern) - [DFS + BFS Patterns (1)](https://medium.com/leetcode-patterns/leetcode-pattern-1-bfs-dfs-25-of-the-problems-part-1-519450a84353) - [DFS + BFS Patterns (2)](https://medium.com/leetcode-patterns/leetcode-pattern-2-dfs-bfs-25-of-the-problems-part-2-a5b269597f52) + +## 📝 Must-Read Leetcode Articles +- [Sliding Window Template](https://leetcode.com/problems/frequency-of-the-most-frequent-element/solutions/1175088/C++-Maximum-Sliding-Window-Cheatsheet-Template/) +- [Two Pointers Patterns](https://leetcode.com/discuss/study-guide/1688903/Solved-all-two-pointers-problems-in-100-days) +- [Collections of Important String Questions](https://leetcode.com/discuss/study-guide/2001789/Collections-of-Important-String-questions-Pattern) +- [Substring Problem Template](https://leetcode.com/problems/minimum-window-substring/solutions/26808/Here-is-a-10-line-template-that-can-solve-most-'substring'-problems/) +- [Binary Search Template](https://leetcode.com/discuss/study-guide/786126/Python-Powerful-Ultimate-Binary-Search-Template.-Solved-many-problems) +- [A General Approach to Backtracking Questions](https://leetcode.com/problems/permutations/solutions/18239/A-general-approach-to-backtracking-questions-in-Java-(Subsets-Permutations-Combination-Sum-Palindrome-Partioning)/) +- [Monotonic Stack Template](https://leetcode.com/discuss/study-guide/2347639/A-comprehensive-guide-and-template-for-monotonic-stack-based-problems) +- [Heap Patterns](https://leetcode.com/discuss/general-discussion/1127238/master-heap-by-solving-23-questions-in-4-patterns-category) +- [Bit Manipulation Patterns](https://leetcode.com/discuss/study-guide/4282051/all-types-of-patterns-for-bits-manipulations-and-how-to-use-it) +- [Dynamic Programming Patterns](https://leetcode.com/discuss/study-guide/458695/Dynamic-Programming-Patterns) - [Stock Series Patterns](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/solutions/108870/most-consistent-ways-of-dealing-with-the-series-of-stock-problems/) ## 📺 YouTube Playlist From 4c58d586f46b0d4dc3e233bc8f0196fa63e8b1bc Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Mon, 22 Jul 2024 23:53:46 -0700 Subject: [PATCH 35/66] Add more leetcode patterns --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f9fd163..5ced793 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,9 @@ This repository contains awesome LeetCode resources to learn Data Structures and ## 🚀 Patterns - [15 Leetcode Patterns](https://blog.algomaster.io/p/15-leetcode-patterns) - [Prefix Sum Pattern](https://blog.algomaster.io/p/f96dd3de-c89c-428e-a88d-b1f751a42a57) -- [Fast and Slow Pointers Pattern](https://medium.com/@arifimran5/fast-and-slow-pointer-pattern-in-linked-list-43647869ac99) +- [Fast and Slow Pointers Pattern](https://blog.algomaster.io/p/7dcce8e9-beee-4fef-8874-7aae025031b1) +- [Top 'K' Elements Pattern](https://blog.algomaster.io/p/322aac40-c4d0-4e54-980d-b22d9eeebca6) +- [Monotonic Stack](https://blog.algomaster.io/p/5dabff21-11f4-470d-8e38-76ff07c63fdf) - [Tree Patterns](https://leetcode.com/discuss/study-guide/937307/Iterative-or-Recursive-or-DFS-and-BFS-Tree-Traversal-or-In-Pre-Post-and-LevelOrder-or-Views) - [Tree Iterative Traversal](https://medium.com/leetcode-patterns/leetcode-pattern-0-iterative-traversals-on-trees-d373568eb0ec) - [Tree Question Pattern](https://leetcode.com/discuss/study-guide/2879240/TREE-QUESTION-PATTERN-2023-oror-TREE-STUDY-GUIDE) From c20c76a94e64b988dc5466643a8bfd781c63e453 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Tue, 23 Jul 2024 00:13:20 -0700 Subject: [PATCH 36/66] Add Overlapping intervals pattern --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 5ced793..a776ee2 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ This repository contains awesome LeetCode resources to learn Data Structures and - [Fast and Slow Pointers Pattern](https://blog.algomaster.io/p/7dcce8e9-beee-4fef-8874-7aae025031b1) - [Top 'K' Elements Pattern](https://blog.algomaster.io/p/322aac40-c4d0-4e54-980d-b22d9eeebca6) - [Monotonic Stack](https://blog.algomaster.io/p/5dabff21-11f4-470d-8e38-76ff07c63fdf) +- [Overlapping Intervals](https://blog.algomaster.io/p/812e72f7-eced-4256-a4c1-00606ae50679) - [Tree Patterns](https://leetcode.com/discuss/study-guide/937307/Iterative-or-Recursive-or-DFS-and-BFS-Tree-Traversal-or-In-Pre-Post-and-LevelOrder-or-Views) - [Tree Iterative Traversal](https://medium.com/leetcode-patterns/leetcode-pattern-0-iterative-traversals-on-trees-d373568eb0ec) - [Tree Question Pattern](https://leetcode.com/discuss/study-guide/2879240/TREE-QUESTION-PATTERN-2023-oror-TREE-STUDY-GUIDE) From ec5538027318edf21c62b78686b4933342c737cb Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Tue, 23 Jul 2024 13:28:48 -0700 Subject: [PATCH 37/66] Add two pointers and sliding window pattern article --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a776ee2..ea080dd 100644 --- a/README.md +++ b/README.md @@ -39,10 +39,12 @@ This repository contains awesome LeetCode resources to learn Data Structures and ## 🚀 Patterns - [15 Leetcode Patterns](https://blog.algomaster.io/p/15-leetcode-patterns) - [Prefix Sum Pattern](https://blog.algomaster.io/p/f96dd3de-c89c-428e-a88d-b1f751a42a57) +- [Two Pointers Pattern](https://blog.algomaster.io/p/69025a2e-b0d5-4705-8507-bba16c2691f1) - [Fast and Slow Pointers Pattern](https://blog.algomaster.io/p/7dcce8e9-beee-4fef-8874-7aae025031b1) +- [Sliding Window Pattern](https://blog.algomaster.io/p/f4412a17-7a3a-4d0b-8e39-9ea8f429bf7c) - [Top 'K' Elements Pattern](https://blog.algomaster.io/p/322aac40-c4d0-4e54-980d-b22d9eeebca6) -- [Monotonic Stack](https://blog.algomaster.io/p/5dabff21-11f4-470d-8e38-76ff07c63fdf) -- [Overlapping Intervals](https://blog.algomaster.io/p/812e72f7-eced-4256-a4c1-00606ae50679) +- [Monotonic Stack Pattern](https://blog.algomaster.io/p/5dabff21-11f4-470d-8e38-76ff07c63fdf) +- [Overlapping Intervals Pattern](https://blog.algomaster.io/p/812e72f7-eced-4256-a4c1-00606ae50679) - [Tree Patterns](https://leetcode.com/discuss/study-guide/937307/Iterative-or-Recursive-or-DFS-and-BFS-Tree-Traversal-or-In-Pre-Post-and-LevelOrder-or-Views) - [Tree Iterative Traversal](https://medium.com/leetcode-patterns/leetcode-pattern-0-iterative-traversals-on-trees-d373568eb0ec) - [Tree Question Pattern](https://leetcode.com/discuss/study-guide/2879240/TREE-QUESTION-PATTERN-2023-oror-TREE-STUDY-GUIDE) From 1b631ead6001af546e68684127b7ba981ced7a5c Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Wed, 24 Jul 2024 14:14:49 -0700 Subject: [PATCH 38/66] Add Backtracking and Modified Binary Search Patterns --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index ea080dd..ce20c52 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,8 @@ This repository contains awesome LeetCode resources to learn Data Structures and - [Top 'K' Elements Pattern](https://blog.algomaster.io/p/322aac40-c4d0-4e54-980d-b22d9eeebca6) - [Monotonic Stack Pattern](https://blog.algomaster.io/p/5dabff21-11f4-470d-8e38-76ff07c63fdf) - [Overlapping Intervals Pattern](https://blog.algomaster.io/p/812e72f7-eced-4256-a4c1-00606ae50679) +- [Backtracking Pattern](https://blog.algomaster.io/p/81d42ca2-600c-4252-aa33-a56462090048) +- [Modified Binary Search Pattern](https://blog.algomaster.io/p/d0d81b04-4c2a-4b45-a101-5137c3146686) - [Tree Patterns](https://leetcode.com/discuss/study-guide/937307/Iterative-or-Recursive-or-DFS-and-BFS-Tree-Traversal-or-In-Pre-Post-and-LevelOrder-or-Views) - [Tree Iterative Traversal](https://medium.com/leetcode-patterns/leetcode-pattern-0-iterative-traversals-on-trees-d373568eb0ec) - [Tree Question Pattern](https://leetcode.com/discuss/study-guide/2879240/TREE-QUESTION-PATTERN-2023-oror-TREE-STUDY-GUIDE) From 6b7bd4ab6e05f355266d7732af473a74cad02330 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Thu, 25 Jul 2024 00:59:46 -0700 Subject: [PATCH 39/66] Add blind 75 list --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ce20c52..f086a4e 100644 --- a/README.md +++ b/README.md @@ -94,9 +94,9 @@ This repository contains awesome LeetCode resources to learn Data Structures and - [LeetCode VS Code Extension](https://marketplace.visualstudio.com/items?itemName=LeetCode.vscode-leetcode): Solve LeetCode problems in VS Code. ## ✅ Curated Problems +- [Blind 75](https://leetcode.com/discuss/general-discussion/460599/blind-75-leetcode-questions) - [Leetcode Top 100 Liked](https://leetcode.com/studyplan/top-100-liked/) - [Leetcode Top Interview 150](https://leetcode.com/studyplan/top-interview-150/) -- [Leetcode 75](https://leetcode.com/studyplan/leetcode-75/) ## 💻 Must-Do Problems (Topic Wise) ### Linked List From 5527ed1a7c401a309eb3553df2ac63fe8f7e4bde Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Sat, 27 Jul 2024 21:21:40 -0700 Subject: [PATCH 40/66] Add DP Patterns --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f086a4e..f99d2a0 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ This repository contains awesome LeetCode resources to learn Data Structures and ## 🚀 Patterns - [15 Leetcode Patterns](https://blog.algomaster.io/p/15-leetcode-patterns) +- [20 DP Patterns](https://blog.algomaster.io/p/20-patterns-to-master-dynamic-programming) - [Prefix Sum Pattern](https://blog.algomaster.io/p/f96dd3de-c89c-428e-a88d-b1f751a42a57) - [Two Pointers Pattern](https://blog.algomaster.io/p/69025a2e-b0d5-4705-8507-bba16c2691f1) - [Fast and Slow Pointers Pattern](https://blog.algomaster.io/p/7dcce8e9-beee-4fef-8874-7aae025031b1) From c5d11d5c5bc570623f1d250c40cbdea20ac630fa Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Mon, 12 Aug 2024 19:13:23 -0700 Subject: [PATCH 41/66] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index f99d2a0..0c649c7 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,6 @@ This repository contains awesome LeetCode resources to learn Data Structures and ## 📇 Courses - [Coursera - Algorithms, Part I](https://www.coursera.org/learn/algorithms-part1) - [Coursera - Algorithms, Part 2](https://www.coursera.org/learn/algorithms-part2) -- [Grokking the Coding Interview: Patterns for Coding Questions](https://www.designgurus.io/course/grokking-the-coding-interview/?aff=mopp8k) ## 📚 Books - [Data Structures And Algorithms Made Easy](https://www.amazon.com/Data-Structures-Algorithms-Made-Easy-ebook/dp/B0CBW278NC/) From c43d9234c782326dd3013b66aaebececd2276b4e Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Tue, 1 Oct 2024 19:29:02 +0530 Subject: [PATCH 42/66] Add graph algorithms article --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0c649c7..d1f3676 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ This repository contains awesome LeetCode resources to learn Data Structures and - [Greedy Algorithm](https://www.freecodecamp.org/news/greedy-algorithms/) - [Dynamic Programming](https://medium.com/basecs/less-repetition-more-dynamic-programming-43d29830a630) - [Graph Theory](https://medium.com/basecs/a-gentle-introduction-to-graph-theory-77969829ead8) +- [Important Graph Algorithms](https://blog.algomaster.io/p/master-graph-algorithms-for-coding) - [DFS Traversal](https://medium.com/basecs/deep-dive-through-a-graph-dfs-traversal-8177df5d0f13) - [BFS Traversal](https://medium.com/basecs/going-broad-in-a-graph-bfs-traversal-959bd1a09255) - [Union-Find](https://leetcode.com/discuss/general-discussion/1072418/Disjoint-Set-Union-(DSU)Union-Find-A-Complete-Guide) From 18edf0085664148cd3e939ada8de9c6af6b00cce Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Mon, 14 Oct 2024 14:04:24 +0530 Subject: [PATCH 43/66] Add fast and slow pointers code --- patterns/c#/FastAndSlowPointers.cs | 95 ++++++++++++++++ patterns/c++/FastAndSlowPointers.cpp | 100 +++++++++++++++++ patterns/go/fast_and_slow_pointers.go | 98 ++++++++++++++++ patterns/java/FastAndSlowPointers.java | 123 +++++++++++++++++++++ patterns/javascript/fastAndSlowPointers.js | 84 ++++++++++++++ patterns/python/fast_and_slow_pointers.py | 68 ++++++++++++ patterns/typescript/fastAndSlowPointers.ts | 86 ++++++++++++++ 7 files changed, 654 insertions(+) create mode 100644 patterns/c#/FastAndSlowPointers.cs create mode 100644 patterns/c++/FastAndSlowPointers.cpp create mode 100644 patterns/go/fast_and_slow_pointers.go create mode 100644 patterns/java/FastAndSlowPointers.java create mode 100644 patterns/javascript/fastAndSlowPointers.js create mode 100644 patterns/python/fast_and_slow_pointers.py create mode 100644 patterns/typescript/fastAndSlowPointers.ts diff --git a/patterns/c#/FastAndSlowPointers.cs b/patterns/c#/FastAndSlowPointers.cs new file mode 100644 index 0000000..280276d --- /dev/null +++ b/patterns/c#/FastAndSlowPointers.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; + +public class ListNode { + public int val; + public ListNode next; + public ListNode(int x) { + val = x; + next = null; + } +} + +public class FastAndSlowPointers { + // LeetCode 141 - Linked List Cycle (HashSet Approach) + public bool HasCycleHashSetApproach(ListNode head) { + HashSet visited = new HashSet(); + ListNode current = head; + while (current != null) { + if (visited.Contains(current)) { + return true; // Cycle detected + } + visited.Add(current); + current = current.next; + } + return false; // No cycle + } + + // LeetCode 141 - Linked List Cycle (Fast and Slow Pointer Approach) + public bool HasCycleFastAndSlowPointersApproach(ListNode head) { + if (head == null || head.next == null) return false; + ListNode slow = head, fast = head; + while (fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; + if (slow == fast) return true; + } + return false; + } + + // LeetCode 876 - Middle of the Linked List (Counting Approach) + public ListNode MiddleNodeCountingApproach(ListNode head) { + int count = 0; + ListNode current = head; + while (current != null) { + count++; + current = current.next; + } + current = head; + for (int i = 0; i < count / 2; i++) { + current = current.next; + } + return current; + } + + // LeetCode 876 - Middle of the Linked List (Fast and Slow Pointer Approach) + public ListNode MiddleNodeFastAndSlowPointerApproach(ListNode head) { + ListNode slow = head, fast = head; + while (fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; + } + return slow; + } + + // LeetCode 202 - Happy Number (HashSet Approach) + private int GetSumOfSquares(int n) { + int sum = 0; + while (n > 0) { + int digit = n % 10; + sum += digit * digit; + n /= 10; + } + return sum; + } + + public bool IsHappyHashSetApproach(int n) { + HashSet seen = new HashSet(); + while (n != 1 && !seen.Contains(n)) { + seen.Add(n); + n = GetSumOfSquares(n); + } + return n == 1; + } + + // LeetCode 202 - Happy Number (Fast and Slow Pointer Approach) + public bool IsHappyFastAndSlowPointersApproach(int n) { + int slow = n; + int fast = GetSumOfSquares(n); + while (fast != 1 && slow != fast) { + slow = GetSumOfSquares(slow); + fast = GetSumOfSquares(GetSumOfSquares(fast)); + } + return fast == 1; + } +} \ No newline at end of file diff --git a/patterns/c++/FastAndSlowPointers.cpp b/patterns/c++/FastAndSlowPointers.cpp new file mode 100644 index 0000000..b296339 --- /dev/null +++ b/patterns/c++/FastAndSlowPointers.cpp @@ -0,0 +1,100 @@ +#include +using namespace std; + +class ListNode { +public: + int val; + ListNode* next; + ListNode(int x) : val(x), next(nullptr) {} +}; + +class FastAndSlowPointers { +public: + // LeetCode 141 - Linked List Cycle (HashSet Approach) + bool hasCycleHashSetApproach(ListNode* head) { + unordered_set visited; + ListNode* current = head; + while (current != nullptr) { + if (visited.find(current) != visited.end()) { + return true; // Cycle detected + } + visited.insert(current); + current = current->next; + } + return false; // No cycle + } + + // LeetCode 141 - Linked List Cycle (Fast and Slow Pointer Approach) + bool hasCycleFastAndSlowPointersApproach(ListNode* head) { + if (head == nullptr || head->next == nullptr) { + return false; + } + ListNode* slow = head; + ListNode* fast = head; + while (fast != nullptr && fast->next != nullptr) { + slow = slow->next; + fast = fast->next->next; + if (slow == fast) { + return true; // Cycle detected + } + } + return false; // No cycle + } + + // LeetCode 876 - Middle of the Linked List (Counting Approach) + ListNode* middleNodeCountingApproach(ListNode* head) { + int count = 0; + ListNode* current = head; + while (current != nullptr) { + count++; + current = current->next; + } + current = head; + for (int i = 0; i < count / 2; i++) { + current = current->next; + } + return current; + } + + // LeetCode 876 - Middle of the Linked List (Fast and Slow Pointer Approach) + ListNode* middleNodeFastAndSlowPointerApproach(ListNode* head) { + ListNode* slow = head; + ListNode* fast = head; + while (fast != nullptr && fast->next != nullptr) { + slow = slow->next; + fast = fast->next->next; + } + return slow; + } + + // LeetCode 202 - Happy Number (HashSet Approach) + int getSumOfSquares(int n) { + int sum = 0; + while (n > 0) { + int digit = n % 10; + sum += digit * digit; + n /= 10; + } + return sum; + } + + bool isHappyHashSetApproach(int n) { + unordered_set seen; + while (n != 1 && seen.find(n) == seen.end()) { + seen.insert(n); + n = getSumOfSquares(n); + } + return n == 1; + } + + // LeetCode 202 - Happy Number (Fast and Slow Pointer Approach) + bool isHappyFastAndSlowPointersApproach(int n) { + int slow = n; + int fast = getSumOfSquares(n); + while (fast != 1 && slow != fast) { + slow = getSumOfSquares(slow); + fast = getSumOfSquares(getSumOfSquares(fast)); + } + return fast == 1; + } +}; \ No newline at end of file diff --git a/patterns/go/fast_and_slow_pointers.go b/patterns/go/fast_and_slow_pointers.go new file mode 100644 index 0000000..f4bb6e0 --- /dev/null +++ b/patterns/go/fast_and_slow_pointers.go @@ -0,0 +1,98 @@ +package main + +import "fmt" + +type ListNode struct { + Val int + Next *ListNode +} + +// LeetCode 141 - Linked List Cycle (HashSet Approach) +func hasCycleHashSetApproach(head *ListNode) bool { + visited := map[*ListNode]bool{} + current := head + for current != nil { + if visited[current] { + return true + } + visited[current] = true + current = current.Next + } + return false +} + +// LeetCode 141 - Linked List Cycle (Fast and Slow Pointer Approach) +func hasCycleFastAndSlowPointersApproach(head *ListNode) bool { + if head == nil || head.Next == nil { + return false + } + slow, fast := head, head + for fast != nil && fast.Next != nil { + slow = slow.Next + fast = fast.Next.Next + if slow == fast { + return true + } + } + return false +} + +// LeetCode 876 - Middle of the Linked List (Counting Approach) +func middleNodeCountingApproach(head *ListNode) *ListNode { + count := 0 + current := head + for current != nil { + count++ + current = current.Next + } + current = head + for i := 0; i < count/2; i++ { + current = current.Next + } + return current +} + +// LeetCode 876 - Middle of the Linked List (Fast and Slow Pointer Approach) +func middleNodeFastAndSlowPointerApproach(head *ListNode) *ListNode { + slow, fast := head, head + for fast != nil && fast.Next != nil { + slow = slow.Next + fast = fast.Next.Next + } + return slow +} + +// LeetCode 202 - Happy Number (HashSet Approach) +func getSumOfSquares(n int) int { + sum := 0 + for n > 0 { + digit := n % 10 + sum += digit * digit + n /= 10 + } + return sum +} + +func isHappyHashSetApproach(n int) bool { + seen := map[int]bool{} + for n != 1 && !seen[n] { + seen[n] = true + n = getSumOfSquares(n) + } + return n == 1 +} + +// LeetCode 202 - Happy Number (Fast and Slow Pointer Approach) +func isHappyFastAndSlowPointersApproach(n int) bool { + slow := n + fast := getSumOfSquares(n) + for fast != 1 && slow != fast { + slow = getSumOfSquares(slow) + fast = getSumOfSquares(getSumOfSquares(fast)) + } + return fast == 1 +} + +func main() { + // You can test the implementations here +} \ No newline at end of file diff --git a/patterns/java/FastAndSlowPointers.java b/patterns/java/FastAndSlowPointers.java new file mode 100644 index 0000000..666e433 --- /dev/null +++ b/patterns/java/FastAndSlowPointers.java @@ -0,0 +1,123 @@ +package patterns.java; + +import java.util.HashSet; + +public class FastAndSlowPointers { + + class ListNode { + int val; + ListNode next; + ListNode(int x) { + val = x; + next = null; + } + } + +/* + * ********** LeetCode 141 - Linked List Cycle (https://leetcode.com/problems/linked-list-cycle/) ********** +*/ + + public boolean hasCycleHashSetAppraoch(ListNode head) { + HashSet visited = new HashSet<>(); + ListNode current = head; + while (current != null) { + if (visited.contains(current)) { + return true; // Cycle detected + } + visited.add(current); + current = current.next; + } + return false; // No cycle + } + + public boolean hasCycleFastAndSlowPointersAppraoch(ListNode head) { + if (head == null || head.next == null) { + return false; // No cycle if the list is empty or has only one node + } + + ListNode slow = head; + ListNode fast = head; + + while (fast != null && fast.next != null) { + slow = slow.next; // Move slow pointer by 1 step + fast = fast.next.next; // Move fast pointer by 2 steps + + if (slow == fast) { + return true; // Cycle detected + } + } + + return false; // No cycle + } + +/* + * ********** LeetCode 876 - Middle of the Linked List (https://leetcode.com/problems/middle-of-the-linked-list/description/) ********** +*/ + + public ListNode middleNodeCountingApproach(ListNode head) { + int count = 0; + ListNode current = head; + + // First pass to count the number of nodes + while (current != null) { + count++; + current = current.next; + } + + // Second pass to find the middle node + current = head; + for (int i = 0; i < count / 2; i++) { + current = current.next; + } + + return current; // This will be the middle node + } + + public ListNode middleNodeFastAndSlowPointerApproach(ListNode head) { + ListNode slow = head; + ListNode fast = head; + + // Move slow by 1 and fast by 2 steps + while (fast != null && fast.next != null) { + slow = slow.next; + fast = fast.next.next; + } + + return slow; // Slow will be at the middle node + } + +/* + * ********** LeetCode 202 - Happy Number (https://leetcode.com/problems/happy-number/description/) ********** +*/ + + private int getSumOfSquares(int n) { + int sum = 0; + while (n > 0) { + int digit = n % 10; + sum += digit * digit; + n /= 10; + } + return sum; + } + + public boolean isHappyHashSetApproach(int n) { + HashSet seen = new HashSet<>(); + while (n != 1 && !seen.contains(n)) { + seen.add(n); + n = getSumOfSquares(n); + } + return n == 1; + } + + public boolean isHappyFastAndSlowPointersApproach(int n) { + int slow = n; + int fast = getSumOfSquares(n); + + while (fast != 1 && slow != fast) { + slow = getSumOfSquares(slow); // Move slow by 1 step + fast = getSumOfSquares(getSumOfSquares(fast)); // Move fast by 2 steps + } + + return fast == 1; + } +} \ No newline at end of file diff --git a/patterns/javascript/fastAndSlowPointers.js b/patterns/javascript/fastAndSlowPointers.js new file mode 100644 index 0000000..0ddc20a --- /dev/null +++ b/patterns/javascript/fastAndSlowPointers.js @@ -0,0 +1,84 @@ +class ListNode { + constructor(x) { + this.val = x; + this.next = null; + } +} + +class FastAndSlowPointers { + // LeetCode 141 - Linked List Cycle (HashSet Approach) + hasCycleHashSetApproach(head) { + const visited = new Set(); + let current = head; + while (current) { + if (visited.has(current)) { + return true; + } + visited.add(current); + current = current.next; + } + return false; + } + + // LeetCode 141 - Linked List Cycle (Fast and Slow Pointer Approach) + hasCycleFastAndSlowPointersApproach(head) { + if (!head || !head.next) return false; + let slow = head, fast = head; + while (fast && fast.next) { + slow = slow.next; + fast = fast.next.next; + if (slow === fast) return true; + } + return false; + } + + // LeetCode 876 - Middle of the Linked List (Counting Approach) + middleNodeCountingApproach(head) { + let count = 0; + let current = head; + while (current) { + count++; + current = current.next; + } + current = head; + for (let i = 0; i < Math.floor(count / 2); i++) { + current = current.next; + } + return current; + } + + // LeetCode 876 - Middle of the Linked List (Fast and Slow Pointer Approach) + middleNodeFastAndSlowPointerApproach(head) { + let slow = head, fast = head; + while (fast && fast.next) { + slow = slow.next; + fast = fast.next.next; + } + return slow; + } + + // LeetCode 202 - Happy Number (HashSet Approach) + getSumOfSquares(n) { + return String(n).split('').reduce((sum, digit) => sum + digit * digit, 0); + } + + isHappyHashSetApproach(n) { + const seen = new Set(); + while (n !== 1 && !seen.has(n)) { + seen.add(n); + n = this.getSumOfSquares(n); + } + return n === 1; + } + + // LeetCode 202 - Happy Number (Fast and Slow Pointer Approach) + isHappyFastAndSlowPointersApproach(n) { + let slow = n; + let fast = this.getSumOfSquares(n); + while (fast !== 1 && slow !== fast) { + slow = this.getSumOfSquares(slow); + fast = this.getSumOfSquares(this.getSumOfSquares(fast)); + } + return fast === 1; + } +} \ No newline at end of file diff --git a/patterns/python/fast_and_slow_pointers.py b/patterns/python/fast_and_slow_pointers.py new file mode 100644 index 0000000..be6ed55 --- /dev/null +++ b/patterns/python/fast_and_slow_pointers.py @@ -0,0 +1,68 @@ +class ListNode: + def __init__(self, x): + self.val = x + self.next = None + +class FastAndSlowPointers: + # LeetCode 141 - Linked List Cycle (HashSet Approach) + def hasCycleHashSetApproach(self, head): + visited = set() + current = head + while current: + if current in visited: + return True + visited.add(current) + current = current.next + return False + + # LeetCode 141 - Linked List Cycle (Fast and Slow Pointer Approach) + def hasCycleFastAndSlowPointersApproach(self, head): + if not head or not head.next: + return False + slow, fast = head, head + while fast and fast.next: + slow = slow.next + fast = fast.next.next + if slow == fast: + return True + return False + + # LeetCode 876 - Middle of the Linked List (Counting Approach) + def middleNodeCountingApproach(self, head): + count = 0 + current = head + while current: + count += 1 + current = current.next + current = head + for _ in range(count // 2): + current = current.next + return current + + # LeetCode 876 - Middle of the Linked List (Fast and Slow Pointer Approach) + def middleNodeFastAndSlowPointerApproach(self, head): + slow, fast = head, head + while fast and fast.next: + slow = slow.next + fast = fast.next.next + return slow + + # LeetCode 202 - Happy Number (HashSet Approach) + def getSumOfSquares(self, n): + return sum(int(digit)**2 for digit in str(n)) + + def isHappyHashSetApproach(self, n): + seen = set() + while n != 1 and n not in seen: + seen.add(n) + n = self.getSumOfSquares(n) + return n == 1 + + # LeetCode 202 - Happy Number (Fast and Slow Pointer Approach) + def isHappyFastAndSlowPointersApproach(self, n): + slow = n + fast = self.getSumOfSquares(n) + while fast != 1 and slow != fast: + slow = self.getSumOfSquares(slow) + fast = self.getSumOfSquares(self.getSumOfSquares(fast)) + return fast == 1 \ No newline at end of file diff --git a/patterns/typescript/fastAndSlowPointers.ts b/patterns/typescript/fastAndSlowPointers.ts new file mode 100644 index 0000000..526baae --- /dev/null +++ b/patterns/typescript/fastAndSlowPointers.ts @@ -0,0 +1,86 @@ +class ListNode { + val: number; + next: ListNode | null = null; + constructor(x: number) { + this.val = x; + } +} + +class FastAndSlowPointers { + // LeetCode 141 - Linked List Cycle (HashSet Approach) + hasCycleHashSetApproach(head: ListNode | null): boolean { + const visited = new Set(); + let current = head; + while (current) { + if (visited.has(current)) { + return true; + } + visited.add(current); + current = current.next; + } + return false; + } + + // LeetCode 141 - Linked List Cycle (Fast and Slow Pointer Approach) + hasCycleFastAndSlowPointersApproach(head: ListNode | null): boolean { + if (!head || !head.next) return false; + let slow: ListNode | null = head; + let fast: ListNode | null = head; + while (fast && fast.next) { + slow = slow!.next; + fast = fast.next.next; + if (slow === fast) return true; + } + return false; + } + + // LeetCode 876 - Middle of the Linked List (Counting Approach) + middleNodeCountingApproach(head: ListNode | null): ListNode | null { + let count = 0; + let current = head; + while (current) { + count++; + current = current.next; + } + current = head; + for (let i = 0; i < Math.floor(count / 2); i++) { + current = current!.next; + } + return current; + } + + // LeetCode 876 - Middle of the Linked List (Fast and Slow Pointer Approach) + middleNodeFastAndSlowPointerApproach(head: ListNode | null): ListNode | null { + let slow = head, fast = head; + while (fast && fast.next) { + slow = slow!.next; + fast = fast.next.next; + } + return slow; + } + + // LeetCode 202 - Happy Number (HashSet Approach) + getSumOfSquares(n: number): number { + return String(n).split('').reduce((sum, digit) => sum + Number(digit) ** 2, 0); + } + + isHappyHashSetApproach(n: number): boolean { + const seen = new Set(); + while (n !== 1 && !seen.has(n)) { + seen.add(n); + n = this.getSumOfSquares(n); + } + return n === 1; + } + + // LeetCode 202 - Happy Number (Fast and Slow Pointer Approach) + isHappyFastAndSlowPointersApproach(n: number): boolean { + let slow = n; + let fast = this.getSumOfSquares(n); + while (fast !== 1 && slow !== fast) { + slow = this.getSumOfSquares(slow); + fast = this.getSumOfSquares(this.getSumOfSquares(fast)); + } + return fast === 1; + } +} \ No newline at end of file From d590ec33a44ab1967673d343d35ef721399ccf4e Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Mon, 14 Oct 2024 14:07:48 +0530 Subject: [PATCH 44/66] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d1f3676..99444f5 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ This repository contains awesome LeetCode resources to learn Data Structures and - [20 DP Patterns](https://blog.algomaster.io/p/20-patterns-to-master-dynamic-programming) - [Prefix Sum Pattern](https://blog.algomaster.io/p/f96dd3de-c89c-428e-a88d-b1f751a42a57) - [Two Pointers Pattern](https://blog.algomaster.io/p/69025a2e-b0d5-4705-8507-bba16c2691f1) -- [Fast and Slow Pointers Pattern](https://blog.algomaster.io/p/7dcce8e9-beee-4fef-8874-7aae025031b1) +- [Linked List In-place Reversal Pattern](https://blog.algomaster.io/p/7dcce8e9-beee-4fef-8874-7aae025031b1) - [Sliding Window Pattern](https://blog.algomaster.io/p/f4412a17-7a3a-4d0b-8e39-9ea8f429bf7c) - [Top 'K' Elements Pattern](https://blog.algomaster.io/p/322aac40-c4d0-4e54-980d-b22d9eeebca6) - [Monotonic Stack Pattern](https://blog.algomaster.io/p/5dabff21-11f4-470d-8e38-76ff07c63fdf) From 7856de92131bb56b367b08ae2bf389c3be02916a Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Wed, 16 Oct 2024 17:04:39 +0530 Subject: [PATCH 45/66] add top k elements pattern code --- patterns/c#/TopKElements.cs | 103 ++++++++++++++++++ patterns/c++/TopKElements.cpp | 111 +++++++++++++++++++ patterns/go/top_k_elements.go | 96 +++++++++++++++++ patterns/java/TopKElements.java | 149 ++++++++++++++++++++++++++ patterns/javascript/top_k_elements.js | 88 +++++++++++++++ patterns/python/top_k_elements.py | 49 +++++++++ patterns/typescript/top_k_elements.ts | 88 +++++++++++++++ 7 files changed, 684 insertions(+) create mode 100644 patterns/c#/TopKElements.cs create mode 100644 patterns/c++/TopKElements.cpp create mode 100644 patterns/go/top_k_elements.go create mode 100644 patterns/java/TopKElements.java create mode 100644 patterns/javascript/top_k_elements.js create mode 100644 patterns/python/top_k_elements.py create mode 100644 patterns/typescript/top_k_elements.ts diff --git a/patterns/c#/TopKElements.cs b/patterns/c#/TopKElements.cs new file mode 100644 index 0000000..7b0b715 --- /dev/null +++ b/patterns/c#/TopKElements.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +public class TopKElements { + + // K Largest Elements using Sorting + public int[] KLargestElementsSortingApproach(int[] nums, int k) { + Array.Sort(nums, (a, b) => b.CompareTo(a)); + return nums.Take(k).ToArray(); + } + + // K Largest Elements using Max Heap + public int[] KLargestElementsMaxHeapApproach(int[] nums, int k) { + PriorityQueue maxHeap = new PriorityQueue(Comparer.Create((a, b) => b - a)); + foreach (var num in nums) { + maxHeap.Enqueue(num, num); + } + var result = new int[k]; + for (int i = 0; i < k; i++) { + result[i] = maxHeap.Dequeue(); + } + return result; + } + + // K Largest Elements using Min Heap + public int[] KLargestElementsMinHeapApproach(int[] nums, int k) { + PriorityQueue minHeap = new PriorityQueue(); + for (int i = 0; i < k; i++) { + minHeap.Enqueue(nums[i], nums[i]); + } + for (int i = k; i < nums.Length; i++) { + minHeap.Enqueue(nums[i], nums[i]); + if (minHeap.Count > k) { + minHeap.Dequeue(); + } + } + var result = new int[k]; + for (int i = 0; i < k; i++) { + result[i] = minHeap.Dequeue(); + } + return result; + } + + // Top K Frequent Elements using Sorting + public int[] TopKFrequentElementsSortingApproach(int[] nums, int k) { + var frequencyMap = new Dictionary(); + foreach (var num in nums) { + if (!frequencyMap.ContainsKey(num)) { + frequencyMap[num] = 0; + } + frequencyMap[num]++; + } + + var sortedEntries = frequencyMap.OrderByDescending(e => e.Value).Take(k).Select(e => e.Key).ToArray(); + return sortedEntries; + } + + // Top K Frequent Elements using Min Heap + public int[] TopKFrequentElementsMinHeapApproach(int[] nums, int k) { + var frequencyMap = new Dictionary(); + foreach (var num in nums) { + if (!frequencyMap.ContainsKey(num)) { + frequencyMap[num] = 0; + } + frequencyMap[num]++; + } + + var minHeap = new PriorityQueue(Comparer.Create((a, b) => a.CompareTo(b))); + foreach (var entry in frequencyMap) { + minHeap.Enqueue(entry.Key, entry.Value); + if (minHeap.Count > k) { + minHeap.Dequeue(); + } + } + + var result = new int[k]; + for (int i = 0; i < k; i++) { + result[i] = minHeap.Dequeue(); + } + return result; + } + + // K Closest Points to Origin using Max Heap + private int GetDistance(int[] point) { + return point[0] * point[0] + point[1] * point[1]; + } + + public int[][] KClosestPointsToOriginMaxHeapApproach(int[][] points, int k) { + PriorityQueue maxHeap = new PriorityQueue(Comparer.Create((a, b) => b - a)); + foreach (var point in points) { + maxHeap.Enqueue(point, GetDistance(point)); + if (maxHeap.Count > k) { + maxHeap.Dequeue(); + } + } + var result = new int[k][]; + for (int i = 0; i < k; i++) { + result[i] = maxHeap.Dequeue(); + } + return result; + } +} \ No newline at end of file diff --git a/patterns/c++/TopKElements.cpp b/patterns/c++/TopKElements.cpp new file mode 100644 index 0000000..71625a6 --- /dev/null +++ b/patterns/c++/TopKElements.cpp @@ -0,0 +1,111 @@ +#include +#include +#include +#include +#include + +using namespace std; + +class TopKElements { +public: + // K Largest Elements using Sorting + vector kLargestElementsSortingAppraoch(vector& nums, int k) { + sort(nums.begin(), nums.end(), greater()); + return vector(nums.begin(), nums.begin() + k); + } + + // K Largest Elements using Max Heap + vector kLargestElementsMaxHeapAppraoch(vector& nums, int k) { + priority_queue maxHeap(nums.begin(), nums.end()); + vector result; + for (int i = 0; i < k; i++) { + result.push_back(maxHeap.top()); + maxHeap.pop(); + } + return result; + } + + // K Largest Elements using Min Heap + vector kLargestElementsMinHeapAppraoch(vector& nums, int k) { + priority_queue, greater> minHeap; + for (int i = 0; i < k; i++) { + minHeap.push(nums[i]); + } + for (int i = k; i < nums.size(); i++) { + minHeap.push(nums[i]); + if (minHeap.size() > k) { + minHeap.pop(); + } + } + vector result; + while (!minHeap.empty()) { + result.push_back(minHeap.top()); + minHeap.pop(); + } + return result; + } + + // Top K Frequent Elements using Sorting + vector topKFrequentElementsSortingApproach(vector& nums, int k) { + unordered_map frequencyMap; + for (int num : nums) { + frequencyMap[num]++; + } + + vector> freqVec(frequencyMap.begin(), frequencyMap.end()); + sort(freqVec.begin(), freqVec.end(), [](pair& a, pair& b) { + return b.second < a.second; + }); + + vector result; + for (int i = 0; i < k; i++) { + result.push_back(freqVec[i].first); + } + return result; + } + + // Top K Frequent Elements using Min Heap + vector topKFrequentElementsMinHeapApproach(vector& nums, int k) { + unordered_map frequencyMap; + for (int num : nums) { + frequencyMap[num]++; + } + + priority_queue, vector>, greater>> minHeap; + for (auto& entry : frequencyMap) { + minHeap.push({entry.second, entry.first}); + if (minHeap.size() > k) { + minHeap.pop(); + } + } + + vector result; + while (!minHeap.empty()) { + result.push_back(minHeap.top().second); + minHeap.pop(); + } + return result; + } + + // K Closest Points to Origin using Max Heap + int getDistance(vector& point) { + return point[0] * point[0] + point[1] * point[1]; + } + + vector> kClosestPointsToOriginMaxHeapApproach(vector>& points, int k) { + priority_queue>> maxHeap; + for (vector& point : points) { + maxHeap.push({getDistance(point), point}); + if (maxHeap.size() > k) { + maxHeap.pop(); + } + } + + vector> result; + while (!maxHeap.empty()) { + result.push_back(maxHeap.top().second); + maxHeap.pop(); + } + return result; + } +}; \ No newline at end of file diff --git a/patterns/go/top_k_elements.go b/patterns/go/top_k_elements.go new file mode 100644 index 0000000..3a8d0f4 --- /dev/null +++ b/patterns/go/top_k_elements.go @@ -0,0 +1,96 @@ +package main + +import ( + "container/heap" + "sort" +) + +// ********** K Largest Elements ********** +// K Largest Elements using Sorting +func kLargestElementsSortingApproach(nums []int, k int) []int { + sort.Sort(sort.Reverse(sort.IntSlice(nums))) + return nums[:k] +} + +// K Largest Elements using Max Heap +func kLargestElementsMaxHeapApproach(nums []int, k int) []int { + h := &MaxHeap{} + heap.Init(h) + for _, num := range nums { + heap.Push(h, num) + } + result := make([]int, k) + for i := 0; i < k; i++ { + result[i] = heap.Pop(h).(int) + } + return result +} + +// K Largest Elements using Min Heap +func kLargestElementsMinHeapApproach(nums []int, k int) []int { + h := &MinHeap{} + heap.Init(h) + for i := 0; i < k; i++ { + heap.Push(h, nums[i]) + } + for i := k; i < len(nums); i++ { + heap.Push(h, nums[i]) + if h.Len() > k { + heap.Pop(h) + } + } + result := make([]int, k) + for i := 0; i < k; i++ { + result[i] = heap.Pop(h).(int) + } + return result +} + +// ********** Helper Structures ********** + +type MaxHeap []int +type MinHeap []int + +func (h MaxHeap) Len() int { return len(h) } +func (h MaxHeap) Less(i, j int) bool { return h[i] > h[j] } // Max heap +func (h MaxHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } +func (h *MaxHeap) Push(x interface{}) { *h = append(*h, x.(int)) } +func (h *MaxHeap) Pop() interface{} { + old := *h + n := len(old) + x := old[n-1] + *h = old[0 : n-1] + return x +} + +func (h MinHeap) Len() int { return len(h) } +func (h MinHeap) Less(i, j int) bool { return h[i] < h[j] } // Min heap +func (h MinHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } +func (h *MinHeap) Push(x interface{}) { *h = append(*h, x.(int)) } +func (h *MinHeap) Pop() interface{} { + old := *h + n := len(old) + x := old[n-1] + *h = old[0 : n-1] + return x +} + +// ********** Main ********** + +func main() { + // Example test cases + nums := []int{3, 2, 1, 5, 6, 4} + k := 2 + + // Sorting Approach + result := kLargestElementsSortingApproach(nums, k) + fmt.Println("K Largest Elements (Sorting Approach):", result) + + // Max Heap Approach + result = kLargestElementsMaxHeapApproach(nums, k) + fmt.Println("K Largest Elements (Max Heap Approach):", result) + + // Min Heap Approach + result = kLargestElementsMinHeapApproach(nums, k) + fmt.Println("K Largest Elements (Min Heap Approach):", result) +} \ No newline at end of file diff --git a/patterns/java/TopKElements.java b/patterns/java/TopKElements.java new file mode 100644 index 0000000..c84c391 --- /dev/null +++ b/patterns/java/TopKElements.java @@ -0,0 +1,149 @@ +package patterns.java; + +import patterns.java.FastAndSlowPointers.ListNode; +import java.util.*; + +public class TopKElements { + + /* + * ********** K Largest Elements ********** + */ + + public int[] kLargestElementsSortingAppraoch(int[] nums, int k) { + // Step 1: Sort the array in descending order + Integer[] numsArray = Arrays.stream(nums).boxed().toArray(Integer[]::new); + Arrays.sort(numsArray, Collections.reverseOrder()); + + // Step 2: Extract the first K elements + int[] result = new int[k]; + for (int i = 0; i < k; i++) { + result[i] = numsArray[i]; + } + return result; + } + + public int[] kLargestElementsMaxHeapAppraoch(int[] nums, int k) { + // Max heap + PriorityQueue maxHeap = new PriorityQueue<>(Collections.reverseOrder()); + + // Add all numbers to the max heap + for (int num : nums) { + maxHeap.add(num); + } + + // Extract the top K largest elements + int[] result = new int[k]; + for (int i = 0; i < k; i++) { + result[i] = maxHeap.poll(); // Extracts the largest element + } + return result; + } + + public int[] kLargestElementsMinHeapAppraoch(int[] nums, int k) { + // Min heap + PriorityQueue minHeap = new PriorityQueue<>(); + + // Add first K elements into the min heap + for(int i = 0; i < k; i++) { + minHeap.add(nums[i]); + } + + // Process the remaining elements + for (int i = k; i < nums.length; i++) { + minHeap.add(nums[i]); + if (minHeap.size() > k) { + minHeap.poll(); + } + } + + // Extract the top K largest elements from the min heap + int[] result = new int[k]; + for (int i = 0; i < k; i++) { + result[i] = minHeap.poll(); + } + return result; + } + + /* + * ********** LeetCode 347 - Top K Frequent Elements (https://leetcode.com/problems/top-k-frequent-elements/description/) ********** + */ + + public int[] topKFrequentElementsSortingApproach(int[] nums, int k) { + // Step 1: Build the frequency map + Map frequencyMap = new HashMap<>(); + for (int num : nums) { + frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1); + } + + // Step 2: Sort the entries by frequency in descending order + List> entryList = new ArrayList<>(frequencyMap.entrySet()); + entryList.sort((a, b) -> b.getValue() - a.getValue()); + + // Step 3: Extract the top K elements + int[] result = new int[k]; + for (int i = 0; i < k; i++) { + result[i] = entryList.get(i).getKey(); + } + + return result; + } + + public int[] topKFrequentElementsMinHeapApproach(int[] nums, int k) { + // Step 1: Build the frequency map + Map frequencyMap = new HashMap<>(); + for (int num : nums) { + frequencyMap.put(num, frequencyMap.getOrDefault(num, 0) + 1); + } + + // Step 2: Use a min heap to keep track of the top K elements + PriorityQueue> minHeap = new PriorityQueue<>( + (a, b) -> a.getValue() - b.getValue() // Compare by frequency + ); + + // Step 3: Add each entry to the heap, and maintain size K + for (Map.Entry entry : frequencyMap.entrySet()) { + minHeap.add(entry); + if (minHeap.size() > k) { + minHeap.poll(); // Remove the element with the lowest frequency + } + } + + // Step 4: Extract the elements from the heap + int[] result = new int[k]; + for (int i = 0; i < k; i++) { + result[i] = minHeap.poll().getKey(); // Get the element (key) from the heap + } + + return result; + } + + /* + * ********** LeetCode 973 - K Closest Points to Origin (https://leetcode.com/problems/k-closest-points-to-origin/description/) ********** + */ + private int getDistance(int[] point) { + return point[0] * point[0] + point[1] * point[1]; // Squared distance to avoid floating-point operations + } + + public int[][] kClosestPointsToOriginMaxHeapApproach(int[][] points, int k) { + // Max heap with custom comparator to compare by distance + PriorityQueue maxHeap = new PriorityQueue<>((a, b) -> getDistance(b) - getDistance(a)); + + // Iterate through all points + for (int[] point : points) { + maxHeap.add(point); // Add the current point to the heap + + // If the heap exceeds size K, remove the farthest point + if (maxHeap.size() > k) { + maxHeap.poll(); // Remove the point with the largest distance (root of max heap) + } + } + + // Convert the remaining points in the heap to the result array + int[][] result = new int[k][2]; + for (int i = 0; i < k; i++) { + result[i] = maxHeap.poll(); + } + + return result; + } +} \ No newline at end of file diff --git a/patterns/javascript/top_k_elements.js b/patterns/javascript/top_k_elements.js new file mode 100644 index 0000000..c8ab028 --- /dev/null +++ b/patterns/javascript/top_k_elements.js @@ -0,0 +1,88 @@ +class TopKElements { + + // K Largest Elements using Sorting + kLargestElementsSortingApproach(nums, k) { + nums.sort((a, b) => b - a); + return nums.slice(0, k); + } + + // K Largest Elements using Max Heap + kLargestElementsMaxHeapApproach(nums, k) { + const maxHeap = new MaxPriorityQueue({ priority: x => x }); + for (const num of nums) { + maxHeap.enqueue(num); + } + const result = []; + for (let i = 0; i < k; i++) { + result.push(maxHeap.dequeue().element); + } + return result; + } + + // K Largest Elements using Min Heap + kLargestElementsMinHeapApproach(nums, k) { + const minHeap = new MinPriorityQueue({ priority: x => x }); + for (let i = 0; i < k; i++) { + minHeap.enqueue(nums[i]); + } + for (let i = k; i < nums.length; i++) { + minHeap.enqueue(nums[i]); + if (minHeap.size() > k) { + minHeap.dequeue(); + } + } + const result = []; + for (let i = 0; i < k; i++) { + result.push(minHeap.dequeue().element); + } + return result; + } + + // Top K Frequent Elements using Sorting + topKFrequentElementsSortingApproach(nums, k) { + const frequencyMap = new Map(); + nums.forEach(num => frequencyMap.set(num, (frequencyMap.get(num) || 0) + 1)); + return Array.from(frequencyMap) + .sort((a, b) => b[1] - a[1]) + .slice(0, k) + .map(entry => entry[0]); + } + + // Top K Frequent Elements using Min Heap + topKFrequentElementsMinHeapApproach(nums, k) { + const frequencyMap = new Map(); + nums.forEach(num => frequencyMap.set(num, (frequencyMap.get(num) || 0) + 1)); + const minHeap = new MinPriorityQueue({ priority: x => x[1] }); + frequencyMap.forEach((value, key) => { + minHeap.enqueue([key, value]); + if (minHeap.size() > k) { + minHeap.dequeue(); + } + }); + const result = []; + for (let i = 0; i < k; i++) { + result.push(minHeap.dequeue().element[0]); + } + return result; + } + + // K Closest Points to Origin using Max Heap + getDistance(point) { + return point[0] ** 2 + point[1] ** 2; + } + + kClosestPointsToOriginMaxHeapApproach(points, k) { + const maxHeap = new MaxPriorityQueue({ priority: point => -this.getDistance(point) }); + points.forEach(point => { + maxHeap.enqueue(point); + if (maxHeap.size() > k) { + maxHeap.dequeue(); + } + }); + const result = []; + for (let i = 0; i < k; i++) { + result.push(maxHeap.dequeue().element); + } + return result; + } +} \ No newline at end of file diff --git a/patterns/python/top_k_elements.py b/patterns/python/top_k_elements.py new file mode 100644 index 0000000..cf234c1 --- /dev/null +++ b/patterns/python/top_k_elements.py @@ -0,0 +1,49 @@ +import heapq +from collections import Counter + +class TopKElements: + + # K Largest Elements using Sorting + def k_largest_elements_sorting_approach(self, nums, k): + return sorted(nums, reverse=True)[:k] + + # K Largest Elements using Max Heap + def k_largest_elements_max_heap_approach(self, nums, k): + return heapq.nlargest(k, nums) + + # K Largest Elements using Min Heap + def k_largest_elements_min_heap_approach(self, nums, k): + min_heap = nums[:k] + heapq.heapify(min_heap) + for num in nums[k:]: + heapq.heappush(min_heap, num) + if len(min_heap) > k: + heapq.heappop(min_heap) + return [heapq.heappop(min_heap) for _ in range(k)][::-1] + + # Top K Frequent Elements using Sorting + def top_k_frequent_elements_sorting_approach(self, nums, k): + count = Counter(nums) + return [num for num, freq in count.most_common(k)] + + # Top K Frequent Elements using Min Heap + def top_k_frequent_elements_min_heap_approach(self, nums, k): + count = Counter(nums) + min_heap = [] + for num, freq in count.items(): + heapq.heappush(min_heap, (freq, num)) + if len(min_heap) > k: + heapq.heappop(min_heap) + return [heapq.heappop(min_heap)[1] for _ in range(k)][::-1] + + # K Closest Points to Origin using Max Heap + def get_distance(self, point): + return point[0] ** 2 + point[1] ** 2 + + def k_closest_points_to_origin_max_heap_approach(self, points, k): + max_heap = [] + for point in points: + heapq.heappush(max_heap, (-self.get_distance(point), point)) + if len(max_heap) > k: + heapq.heappop(max_heap) + return [heapq.heappop(max_heap)[1] for _ in range(k)][::-1] \ No newline at end of file diff --git a/patterns/typescript/top_k_elements.ts b/patterns/typescript/top_k_elements.ts new file mode 100644 index 0000000..32ff24e --- /dev/null +++ b/patterns/typescript/top_k_elements.ts @@ -0,0 +1,88 @@ +class TopKElements { + + // K Largest Elements using Sorting + kLargestElementsSortingApproach(nums: number[], k: number): number[] { + nums.sort((a, b) => b - a); + return nums.slice(0, k); + } + + // K Largest Elements using Max Heap + kLargestElementsMaxHeapApproach(nums: number[], k: number): number[] { + const maxHeap = new MaxPriorityQueue({ priority: (x: number) => x }); + for (const num of nums) { + maxHeap.enqueue(num); + } + const result: number[] = []; + for (let i = 0; i < k; i++) { + result.push(maxHeap.dequeue().element); + } + return result; + } + + // K Largest Elements using Min Heap + kLargestElementsMinHeapApproach(nums: number[], k: number): number[] { + const minHeap = new MinPriorityQueue({ priority: (x: number) => x }); + for (let i = 0; i < k; i++) { + minHeap.enqueue(nums[i]); + } + for (let i = k; i < nums.length; i++) { + minHeap.enqueue(nums[i]); + if (minHeap.size() > k) { + minHeap.dequeue(); + } + } + const result: number[] = []; + for (let i = 0; i < k; i++) { + result.push(minHeap.dequeue().element); + } + return result; + } + + // Top K Frequent Elements using Sorting + topKFrequentElementsSortingApproach(nums: number[], k: number): number[] { + const frequencyMap = new Map(); + nums.forEach(num => frequencyMap.set(num, (frequencyMap.get(num) || 0) + 1)); + return Array.from(frequencyMap) + .sort((a, b) => b[1] - a[1]) + .slice(0, k) + .map(entry => entry[0]); + } + + // Top K Frequent Elements using Min Heap + topKFrequentElementsMinHeapApproach(nums: number[], k: number): number[] { + const frequencyMap = new Map(); + nums.forEach(num => frequencyMap.set(num, (frequencyMap.get(num) || 0) + 1)); + const minHeap = new MinPriorityQueue({ priority: (x: [number, number]) => x[1] }); + frequencyMap.forEach((value, key) => { + minHeap.enqueue([key, value]); + if (minHeap.size() > k) { + minHeap.dequeue(); + } + }); + const result: number[] = []; + for (let i = 0; i < k; i++) { + result.push(minHeap.dequeue().element[0]); + } + return result; + } + + // K Closest Points to Origin using Max Heap + getDistance(point: number[]): number { + return point[0] ** 2 + point[1] ** 2; + } + + kClosestPointsToOriginMaxHeapApproach(points: number[][], k: number): number[][] { + const maxHeap = new MaxPriorityQueue({ priority: (point: number[]) => -this.getDistance(point) }); + points.forEach(point => { + maxHeap.enqueue(point); + if (maxHeap.size() > k) { + maxHeap.dequeue(); + } + }); + const result: number[][] = []; + for (let i = 0; i < k; i++) { + result.push(maxHeap.dequeue().element); + } + return result; + } +} \ No newline at end of file From 5951b659dc8b8be27500428e730704c938aaaf90 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Thu, 24 Oct 2024 08:35:05 +0530 Subject: [PATCH 46/66] Update links --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 99444f5..863f6df 100644 --- a/README.md +++ b/README.md @@ -80,8 +80,8 @@ This repository contains awesome LeetCode resources to learn Data Structures and - [Coursera - Algorithms, Part 2](https://www.coursera.org/learn/algorithms-part2) ## 📚 Books -- [Data Structures And Algorithms Made Easy](https://www.amazon.com/Data-Structures-Algorithms-Made-Easy-ebook/dp/B0CBW278NC/) -- [Cracking the Coding Interview](https://www.amazon.com/Cracking-Coding-Interview-Programming-Questions/dp/0984782850/) +- [Data Structures And Algorithms Made Easy](https://amzn.to/40bsEUF) +- [Cracking the Coding Interview](https://amzn.to/4e4HNdE) ## 🔎 Visualization - [VisuAlgo](https://visualgo.net/en) From 286d2dc8e978447d65a514bba61160de2764cae1 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Mon, 28 Oct 2024 19:21:16 +0530 Subject: [PATCH 47/66] add level order traversal code --- patterns/c#/LevelOrderTraversal.cs | 30 ++++++++++++++ patterns/c++/LevelOrderTraversal.cpp | 32 +++++++++++++++ patterns/go/level_order_traversal.go | 39 +++++++++++++++++++ patterns/java/LevelOrderTraversal.java | 33 ++++++++++++++++ patterns/javascript/levelOrderTraversal.js | 24 ++++++++++++ .../{top_k_elements.js => topKElements.js} | 0 patterns/python/level_order_traversal.py | 25 ++++++++++++ patterns/typescript/levelOrderTraversal.ts | 28 +++++++++++++ .../{top_k_elements.ts => topKElements.ts} | 0 9 files changed, 211 insertions(+) create mode 100644 patterns/c#/LevelOrderTraversal.cs create mode 100644 patterns/c++/LevelOrderTraversal.cpp create mode 100644 patterns/go/level_order_traversal.go create mode 100644 patterns/java/LevelOrderTraversal.java create mode 100644 patterns/javascript/levelOrderTraversal.js rename patterns/javascript/{top_k_elements.js => topKElements.js} (100%) create mode 100644 patterns/python/level_order_traversal.py create mode 100644 patterns/typescript/levelOrderTraversal.ts rename patterns/typescript/{top_k_elements.ts => topKElements.ts} (100%) diff --git a/patterns/c#/LevelOrderTraversal.cs b/patterns/c#/LevelOrderTraversal.cs new file mode 100644 index 0000000..05b2a53 --- /dev/null +++ b/patterns/c#/LevelOrderTraversal.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; + +public class TreeNode { + public int val; + public TreeNode left; + public TreeNode right; + + public TreeNode(int x) { + val = x; + } +} + +public class LevelOrderTraversal { + public void LevelOrder(TreeNode root) { + if (root == null) return; + + Queue queue = new Queue(); + queue.Enqueue(root); + + while (queue.Count > 0) { + TreeNode node = queue.Dequeue(); + Console.Write(node.val + " "); // Process the node by printing its value + + // Add the left and right children to the queue, if they exist + if (node.left != null) queue.Enqueue(node.left); + if (node.right != null) queue.Enqueue(node.right); + } + } +} \ No newline at end of file diff --git a/patterns/c++/LevelOrderTraversal.cpp b/patterns/c++/LevelOrderTraversal.cpp new file mode 100644 index 0000000..d32a116 --- /dev/null +++ b/patterns/c++/LevelOrderTraversal.cpp @@ -0,0 +1,32 @@ +#include +#include +using namespace std; + +// Definition for a binary tree node. +struct TreeNode { + int val; + TreeNode* left; + TreeNode* right; + + TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} +}; + +class LevelOrderTraversal { +public: + void levelOrder(TreeNode* root) { + if (root == nullptr) return; + + queue q; + q.push(root); + + while (!q.empty()) { + TreeNode* node = q.front(); + q.pop(); + cout << node->val << " "; // Process the node by printing its value + + // Add the left and right children to the queue, if they exist + if (node->left != nullptr) q.push(node->left); + if (node->right != nullptr) q.push(node->right); + } + } +}; \ No newline at end of file diff --git a/patterns/go/level_order_traversal.go b/patterns/go/level_order_traversal.go new file mode 100644 index 0000000..04e388e --- /dev/null +++ b/patterns/go/level_order_traversal.go @@ -0,0 +1,39 @@ +package main + +import "fmt" + +// Definition for a binary tree node. +type TreeNode struct { + Val int + Left *TreeNode + Right *TreeNode +} + +func levelOrder(root *TreeNode) { + if root == nil { + return + } + + queue := []*TreeNode{root} + + for len(queue) > 0 { + node := queue[0] + queue = queue[1:] + fmt.Print(node.Val, " ") // Process the node by printing its value + + // Add the left and right children to the queue, if they exist + if node.Left != nil { + queue = append(queue, node.Left) + } + if node.Right != nil { + queue = append(queue, node.Right) + } +} + +func main() { + // Example usage + root := &TreeNode{Val: 1} + root.Left = &TreeNode{Val: 2} + root.Right = &TreeNode{Val: 3} + levelOrder(root) // Output: 1 2 3 +} \ No newline at end of file diff --git a/patterns/java/LevelOrderTraversal.java b/patterns/java/LevelOrderTraversal.java new file mode 100644 index 0000000..ac56f0f --- /dev/null +++ b/patterns/java/LevelOrderTraversal.java @@ -0,0 +1,33 @@ +package patterns.java; + +import java.util.LinkedList; +import java.util.Queue; + +// Definition for a binary tree node. +class TreeNode { + int val; + TreeNode left; + TreeNode right; + + TreeNode(int x) { + val = x; + } +} + +public class LevelOrderTraversal { + public void levelOrder(TreeNode root) { + if (root == null) return; + + Queue queue = new LinkedList<>(); + queue.add(root); + + while (!queue.isEmpty()) { + TreeNode node = queue.poll(); + System.out.print(node.val + " "); // Process the node by printing its value + + // Add the left and right children to the queue, if they exist + if (node.left != null) queue.add(node.left); + if (node.right != null) queue.add(node.right); + } + } +} diff --git a/patterns/javascript/levelOrderTraversal.js b/patterns/javascript/levelOrderTraversal.js new file mode 100644 index 0000000..c65bab9 --- /dev/null +++ b/patterns/javascript/levelOrderTraversal.js @@ -0,0 +1,24 @@ +// Definition for a binary tree node. +class TreeNode { + constructor(val) { + this.val = val; + this.left = this.right = null; + } +} + +class LevelOrderTraversal { + levelOrder(root) { + if (root === null) return; + + const queue = [root]; + + while (queue.length > 0) { + const node = queue.shift(); + console.log(node.val); // Process the node by printing its value + + // Add the left and right children to the queue, if they exist + if (node.left !== null) queue.push(node.left); + if (node.right !== null) queue.push(node.right); + } + } +} \ No newline at end of file diff --git a/patterns/javascript/top_k_elements.js b/patterns/javascript/topKElements.js similarity index 100% rename from patterns/javascript/top_k_elements.js rename to patterns/javascript/topKElements.js diff --git a/patterns/python/level_order_traversal.py b/patterns/python/level_order_traversal.py new file mode 100644 index 0000000..c52fc99 --- /dev/null +++ b/patterns/python/level_order_traversal.py @@ -0,0 +1,25 @@ +from collections import deque + +# Definition for a binary tree node. +class TreeNode: + def __init__(self, x): + self.val = x + self.left = None + self.right = None + +class LevelOrderTraversal: + def level_order(self, root): + if root is None: + return + + queue = deque([root]) + + while queue: + node = queue.popleft() + print(node.val, end=" ") # Process the node by printing its value + + # Add the left and right children to the queue, if they exist + if node.left: + queue.append(node.left) + if node.right: + queue.append(node.right) \ No newline at end of file diff --git a/patterns/typescript/levelOrderTraversal.ts b/patterns/typescript/levelOrderTraversal.ts new file mode 100644 index 0000000..dfbbcb3 --- /dev/null +++ b/patterns/typescript/levelOrderTraversal.ts @@ -0,0 +1,28 @@ +// Definition for a binary tree node. +class BinaryTreeNode { + val: number; + left: TreeNode | null; + right: TreeNode | null; + + constructor(val: number) { + this.val = val; + this.left = this.right = null; + } +} + +class BinaryTreeLevelOrderTraversal { + levelOrder(root: BinaryTreeNode | null): void { + if (root === null) return; + + const queue: BinaryTreeNode[] = [root]; + + while (queue.length > 0) { + const node = queue.shift()!; + console.log(node.val); // Process the node by printing its value + + // Add the left and right children to the queue, if they exist + if (node.left !== null) queue.push(node.left); + if (node.right !== null) queue.push(node.right); + } + } +} \ No newline at end of file diff --git a/patterns/typescript/top_k_elements.ts b/patterns/typescript/topKElements.ts similarity index 100% rename from patterns/typescript/top_k_elements.ts rename to patterns/typescript/topKElements.ts From bdc2673a6905d26b936f825a68031068a1810932 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Mon, 28 Oct 2024 22:24:23 +0530 Subject: [PATCH 48/66] Update some of the pattern links to youtube videos --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 863f6df..43b7a89 100644 --- a/README.md +++ b/README.md @@ -40,11 +40,12 @@ This repository contains awesome LeetCode resources to learn Data Structures and ## 🚀 Patterns - [15 Leetcode Patterns](https://blog.algomaster.io/p/15-leetcode-patterns) - [20 DP Patterns](https://blog.algomaster.io/p/20-patterns-to-master-dynamic-programming) -- [Prefix Sum Pattern](https://blog.algomaster.io/p/f96dd3de-c89c-428e-a88d-b1f751a42a57) +- [Prefix Sum Pattern](https://www.youtube.com/watch?v=yuws7YK0Yng) +- [Top 'K' Elements Pattern](https://www.youtube.com/watch?v=6_v6OoxvMOE) +- [Fast and Slow Pointers Pattern](https://www.youtube.com/watch?v=b139yf7Ik-E) - [Two Pointers Pattern](https://blog.algomaster.io/p/69025a2e-b0d5-4705-8507-bba16c2691f1) - [Linked List In-place Reversal Pattern](https://blog.algomaster.io/p/7dcce8e9-beee-4fef-8874-7aae025031b1) - [Sliding Window Pattern](https://blog.algomaster.io/p/f4412a17-7a3a-4d0b-8e39-9ea8f429bf7c) -- [Top 'K' Elements Pattern](https://blog.algomaster.io/p/322aac40-c4d0-4e54-980d-b22d9eeebca6) - [Monotonic Stack Pattern](https://blog.algomaster.io/p/5dabff21-11f4-470d-8e38-76ff07c63fdf) - [Overlapping Intervals Pattern](https://blog.algomaster.io/p/812e72f7-eced-4256-a4c1-00606ae50679) - [Backtracking Pattern](https://blog.algomaster.io/p/81d42ca2-600c-4252-aa33-a56462090048) From 607e9df4344e5d6765b3454c51ef0d11a190f78c Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Sun, 24 Nov 2024 18:59:51 +0530 Subject: [PATCH 49/66] Add AlgoMaster 200 list --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 43b7a89..3beeaaa 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,7 @@ This repository contains awesome LeetCode resources to learn Data Structures and - [LeetCode VS Code Extension](https://marketplace.visualstudio.com/items?itemName=LeetCode.vscode-leetcode): Solve LeetCode problems in VS Code. ## ✅ Curated Problems +- [AlgoMaster 200](https://algomaster.io/practice/dsa-patterns) - [Blind 75](https://leetcode.com/discuss/general-discussion/460599/blind-75-leetcode-questions) - [Leetcode Top 100 Liked](https://leetcode.com/studyplan/top-100-liked/) - [Leetcode Top Interview 150](https://leetcode.com/studyplan/top-interview-150/) From 1da1cb4175cbda83f03c35f375c3c37429668299 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Sun, 22 Dec 2024 16:47:34 +0530 Subject: [PATCH 50/66] Update AlgoMaster Link --- README.md | 81 ++++++------------------------------------------------- 1 file changed, 8 insertions(+), 73 deletions(-) diff --git a/README.md b/README.md index 3beeaaa..098544f 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ This repository contains awesome LeetCode resources to learn Data Structures and Algorithms (DSA) and prepare for Coding interviews. +If you want to practice curated list of LeetCode problems organized by patterns, checkout [AlgoMaster.io](https://algomaster.io) + ## 💡 Tips - [How to Start LeetCode](https://www.youtube.com/watch?v=Nx4bvwU0DqE) - [How I Mastered DSA](https://blog.algomaster.io/p/how-i-mastered-data-structures-and-algorithms) @@ -84,6 +86,12 @@ This repository contains awesome LeetCode resources to learn Data Structures and - [Data Structures And Algorithms Made Easy](https://amzn.to/40bsEUF) - [Cracking the Coding Interview](https://amzn.to/4e4HNdE) +## ✅ Curated Problems +- [AlgoMaster 300](https://algomaster.io/practice/dsa-patterns) +- [Blind 75](https://leetcode.com/discuss/general-discussion/460599/blind-75-leetcode-questions) +- [Leetcode Top 100 Liked](https://leetcode.com/studyplan/top-100-liked/) +- [Leetcode Top Interview 150](https://leetcode.com/studyplan/top-interview-150/) + ## 🔎 Visualization - [VisuAlgo](https://visualgo.net/en) - [Algo-lens: Visualize leetcode problems](https://github.com/jaroslaw-weber/algo-lens) @@ -95,77 +103,4 @@ This repository contains awesome LeetCode resources to learn Data Structures and - [LeetHub v2](https://chromewebstore.google.com/detail/leethub-v2/mhanfgfagplhgemhjfeolkkdidbakocm?hl=en): Automatically integrate your Leetcode & GeeksforGeeks submissions to GitHub. - [LeetCode VS Code Extension](https://marketplace.visualstudio.com/items?itemName=LeetCode.vscode-leetcode): Solve LeetCode problems in VS Code. -## ✅ Curated Problems -- [AlgoMaster 200](https://algomaster.io/practice/dsa-patterns) -- [Blind 75](https://leetcode.com/discuss/general-discussion/460599/blind-75-leetcode-questions) -- [Leetcode Top 100 Liked](https://leetcode.com/studyplan/top-100-liked/) -- [Leetcode Top Interview 150](https://leetcode.com/studyplan/top-interview-150/) - -## 💻 Must-Do Problems (Topic Wise) -### Linked List -- [Reverse Linked List](https://leetcode.com/problems/reverse-linked-list/description/) -- [Linked List Cycle](https://leetcode.com/problems/linked-list-cycle/description/) -- [Merge Two Sorted Lists](https://leetcode.com/problems/merge-two-sorted-lists/description/) -- [Intersection of Two Linked Lists](https://leetcode.com/problems/intersection-of-two-linked-lists/description/) -- [Remove Nth Node From End of List](https://leetcode.com/problems/remove-nth-node-from-end-of-list/description/) -- [Add Two Numbers](https://leetcode.com/problems/add-two-numbers/description/) -- [Copy List with Random Pointer](https://leetcode.com/problems/copy-list-with-random-pointer/description/) -- [Flatten a Multilevel Doubly Linked List](https://leetcode.com/problems/flatten-a-multilevel-doubly-linked-list) -- [Rotate List](https://leetcode.com/problems/rotate-list/description/) -- [Sort List](https://leetcode.com/problems/sort-list/description/) -- [Remove Duplicates from Sorted List II](https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/description/) -- [LRU Cache](https://leetcode.com/problems/lru-cache/description/) -- [Design Browser History](https://leetcode.com/problems/design-browser-history/description/) -- [Merge k Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists/description/) -- [Reverse Nodes in k-Group](https://leetcode.com/problems/reverse-nodes-in-k-group/description/) -### Binary Trees - - [Invert Binary Tree](https://leetcode.com/problems/invert-binary-tree/description/) - - [Convert Sorted Array to Binary Search Tree](https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/description/) - - [Count Complete Tree Nodes](https://leetcode.com/problems/count-complete-tree-nodes/description/) - - [All Possible Full Binary Trees](https://leetcode.com/problems/all-possible-full-binary-trees/description/) - - [Delete Leaves With a Given Value](https://leetcode.com/problems/delete-leaves-with-a-given-value/description/) - - [Binary Search Tree Iterator](https://leetcode.com/problems/binary-search-tree-iterator/description/) - - [Longest Univalue Path](https://leetcode.com/problems/longest-univalue-path/description/) - - [Delete Nodes And Return Forest](https://leetcode.com/problems/delete-nodes-and-return-forest/description/) - - [Validate Binary Search Tree](https://leetcode.com/problems/validate-binary-search-tree/description/) - - [Construct Binary Tree from Inorder and Postorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/description/) - - [All Nodes Distance K in Binary Tree](https://leetcode.com/problems/all-nodes-distance-k-in-binary-tree/description/) - - [Maximum Difference Between Node and Ancestor](https://leetcode.com/problems/maximum-difference-between-node-and-ancestor/description/) - - [Find Duplicate Subtrees](https://leetcode.com/problems/find-duplicate-subtrees/description/) - - [Flatten Binary Tree to Linked List](https://leetcode.com/problems/flatten-binary-tree-to-linked-list/description/) - - [House Robber III](https://leetcode.com/problems/house-robber-iii/description/) - - [Step-By-Step Directions From a Binary Tree Node to Another](https://leetcode.com/problems/step-by-step-directions-from-a-binary-tree-node-to-another/description/) - - [Delete Node in a BST](https://leetcode.com/problems/delete-node-in-a-bst/description/) - - [Populating Next Right Pointers in Each Node II](https://leetcode.com/problems/populating-next-right-pointers-in-each-node-ii/description/) - - [Trim a Binary Search Tree](https://leetcode.com/problems/trim-a-binary-search-tree/description/) - - [Distribute Coins in Binary Tree](https://leetcode.com/problems/distribute-coins-in-binary-tree/description/) - - [Binary Search Tree to Greater Sum Tree](https://leetcode.com/problems/binary-search-tree-to-greater-sum-tree/description/) - - [Serialize and Deserialize Binary Tree](https://leetcode.com/problems/serialize-and-deserialize-binary-tree/description/) - - [Binary Tree Cameras](https://leetcode.com/problems/binary-tree-cameras/description/) - - [Binary Tree Maximum Path Sum](https://leetcode.com/problems/binary-tree-maximum-path-sum/description/) - - [Maximum Sum BST in Binary Tree](https://leetcode.com/problems/maximum-sum-bst-in-binary-tree/description/) -### Backtracking -- [Permutations](https://leetcode.com/problems/permutations/description/) -- [Subsets](https://leetcode.com/problems/subsets/description/) -- [Generate Parentheses](https://leetcode.com/problems/generate-parentheses/description/) -- [Combination Sum](https://leetcode.com/problems/combination-sum/description/) -- [Palindrome Partitioning](https://leetcode.com/problems/palindrome-partitioning/description/) -- [Letter Combinations of a Phone Number](https://leetcode.com/problems/letter-combinations-of-a-phone-number/description/) -- [Unique Binary Search Trees II](https://leetcode.com/problems/unique-binary-search-trees-ii/description/) -- [Partition to K Equal Sum Subsets](https://leetcode.com/problems/partition-to-k-equal-sum-subsets/description/) -- [N-Queens II](https://leetcode.com/problems/n-queens-ii/description/) -- [Sudoku Solver](https://leetcode.com/problems/sudoku-solver/description/) -### Tries - - [Implement Trie (Prefix Tree)](https://leetcode.com/problems/implement-trie-prefix-tree/description/) - - [Longest Common Prefix](https://leetcode.com/problems/longest-common-prefix/description/) - - [Search Suggestions System](https://leetcode.com/problems/search-suggestions-system/description/) - - [Longest Word in Dictionary](https://leetcode.com/problems/longest-word-in-dictionary/description/) - - [Top K Frequent Words](https://leetcode.com/problems/top-k-frequent-words/description/) - - [Design Add and Search Words Data Structure](https://leetcode.com/problems/design-add-and-search-words-data-structure/description/) - - [Implement Magic Dictionary](https://leetcode.com/problems/implement-magic-dictionary/description/) - - [Replace Words](https://leetcode.com/problems/replace-words/description/) - - [Word Search II](https://leetcode.com/problems/word-search-ii/description/) - - [Stream of Characters](https://leetcode.com/problems/stream-of-characters/description/) - - Your contributions are most welcome! From a0560c429da96edd810183beac0f2b92daf87cdb Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Mon, 30 Dec 2024 16:51:47 +0530 Subject: [PATCH 51/66] add kadane algorithm --- patterns/c#/KadaneAlgorithm.cs | 14 ++++++++++++++ patterns/c++/KadaneAlgorithm.cpp | 0 patterns/go/kadane_algorithm.go | 15 +++++++++++++++ patterns/java/KadaneAlgorithm.java | 17 +++++++++++++++++ patterns/javascript/kadaneAlgorithm.js | 12 ++++++++++++ patterns/python/kadane_algorithm.py | 10 ++++++++++ patterns/typescript/kadaneAlgorithm.ts | 12 ++++++++++++ 7 files changed, 80 insertions(+) create mode 100644 patterns/c#/KadaneAlgorithm.cs create mode 100644 patterns/c++/KadaneAlgorithm.cpp create mode 100644 patterns/go/kadane_algorithm.go create mode 100644 patterns/java/KadaneAlgorithm.java create mode 100644 patterns/javascript/kadaneAlgorithm.js create mode 100644 patterns/python/kadane_algorithm.py create mode 100644 patterns/typescript/kadaneAlgorithm.ts diff --git a/patterns/c#/KadaneAlgorithm.cs b/patterns/c#/KadaneAlgorithm.cs new file mode 100644 index 0000000..f27991b --- /dev/null +++ b/patterns/c#/KadaneAlgorithm.cs @@ -0,0 +1,14 @@ +using System; + +public class KadaneAlgorithm { + public int MaxSubArray(int[] nums) { + int currentSum = nums[0]; + int maxSum = nums[0]; + + for (int i = 1; i < nums.Length; i++) { + currentSum = Math.Max(nums[i], currentSum + nums[i]); + maxSum = Math.Max(maxSum, currentSum); + } + return maxSum; + } +} \ No newline at end of file diff --git a/patterns/c++/KadaneAlgorithm.cpp b/patterns/c++/KadaneAlgorithm.cpp new file mode 100644 index 0000000..e69de29 diff --git a/patterns/go/kadane_algorithm.go b/patterns/go/kadane_algorithm.go new file mode 100644 index 0000000..4832097 --- /dev/null +++ b/patterns/go/kadane_algorithm.go @@ -0,0 +1,15 @@ +package main + +import "math" + +func maxSubArray(nums []int) int { + currentSum := nums[0] + maxSum := nums[0] + + for i := 1; i < len(nums); i++ { + currentSum = int(math.Max(float64(nums[i]), float64(currentSum+nums[i]))) + maxSum = int(math.Max(float64(maxSum), float64(currentSum))) + } + + return maxSum +} diff --git a/patterns/java/KadaneAlgorithm.java b/patterns/java/KadaneAlgorithm.java new file mode 100644 index 0000000..9e3f46b --- /dev/null +++ b/patterns/java/KadaneAlgorithm.java @@ -0,0 +1,17 @@ +package patterns.java; + +public class KadaneAlgorithm { + public int maxSubArray(int[] nums) { + int currentSum = nums[0]; // Start with the first element + int maxSum = nums[0]; // Initialize maxSum with the first element + + // Traverse the array from the second element + for (int i = 1; i < nums.length; i++) { + // If currentSum is negative, reset to current element + currentSum = Math.max(nums[i], currentSum + nums[i]); + // Update maxSum if currentSum is greater + maxSum = Math.max(maxSum, currentSum); + } + return maxSum; + } +} \ No newline at end of file diff --git a/patterns/javascript/kadaneAlgorithm.js b/patterns/javascript/kadaneAlgorithm.js new file mode 100644 index 0000000..859b036 --- /dev/null +++ b/patterns/javascript/kadaneAlgorithm.js @@ -0,0 +1,12 @@ +class KadaneAlgorithm { + maxSubArray(nums) { + let currentSum = nums[0]; + let maxSum = nums[0]; + + for (let i = 1; i < nums.length; i++) { + currentSum = Math.max(nums[i], currentSum + nums[i]); + maxSum = Math.max(maxSum, currentSum); + } + return maxSum; + } +} \ No newline at end of file diff --git a/patterns/python/kadane_algorithm.py b/patterns/python/kadane_algorithm.py new file mode 100644 index 0000000..66bdd33 --- /dev/null +++ b/patterns/python/kadane_algorithm.py @@ -0,0 +1,10 @@ +class KadaneAlgorithm: + def max_sub_array(self, nums): + current_sum = nums[0] + max_sum = nums[0] + + for i in range(1, len(nums)): + current_sum = max(nums[i], current_sum + nums[i]) + max_sum = max(max_sum, current_sum) + + return max_sum \ No newline at end of file diff --git a/patterns/typescript/kadaneAlgorithm.ts b/patterns/typescript/kadaneAlgorithm.ts new file mode 100644 index 0000000..5b91e80 --- /dev/null +++ b/patterns/typescript/kadaneAlgorithm.ts @@ -0,0 +1,12 @@ +class KadaneAlgorithm { + maxSubArray(nums: number[]): number { + let currentSum: number = nums[0]; + let maxSum: number = nums[0]; + + for (let i = 1; i < nums.length; i++) { + currentSum = Math.max(nums[i], currentSum + nums[i]); + maxSum = Math.max(maxSum, currentSum); + } + return maxSum; + } +} \ No newline at end of file From 60f6b05fd332ecfca3b8f773e40bc90aa1bf3736 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Mon, 30 Dec 2024 18:37:44 +0530 Subject: [PATCH 52/66] Add Kadane's algorithm --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 098544f..c5b920b 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ If you want to practice curated list of LeetCode problems organized by patterns, - [Prefix Sum Pattern](https://www.youtube.com/watch?v=yuws7YK0Yng) - [Top 'K' Elements Pattern](https://www.youtube.com/watch?v=6_v6OoxvMOE) - [Fast and Slow Pointers Pattern](https://www.youtube.com/watch?v=b139yf7Ik-E) +- [Kadane's Algorithm](https://www.youtube.com/watch?v=NUWAXbSlsws) - [Two Pointers Pattern](https://blog.algomaster.io/p/69025a2e-b0d5-4705-8507-bba16c2691f1) - [Linked List In-place Reversal Pattern](https://blog.algomaster.io/p/7dcce8e9-beee-4fef-8874-7aae025031b1) - [Sliding Window Pattern](https://blog.algomaster.io/p/f4412a17-7a3a-4d0b-8e39-9ea8f429bf7c) From 07bff6b32b8c46f38cf803c0c96416b8b97c19f5 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Mon, 30 Dec 2024 22:35:33 +0530 Subject: [PATCH 53/66] add algomaster leetcode pattern playlist link --- README.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c5b920b..78ca9c5 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,14 @@ If you want to practice curated list of LeetCode problems organized by patterns, - [Dynamic Programming Patterns](https://leetcode.com/discuss/study-guide/458695/Dynamic-Programming-Patterns) - [Stock Series Patterns](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/solutions/108870/most-consistent-ways-of-dealing-with-the-series-of-stock-problems/) +## ✅ Curated Problems +- [AlgoMaster 300](https://algomaster.io/practice/dsa-patterns) +- [Blind 75](https://leetcode.com/discuss/general-discussion/460599/blind-75-leetcode-questions) +- [Leetcode Top 100 Liked](https://leetcode.com/studyplan/top-100-liked/) +- [Leetcode Top Interview 150](https://leetcode.com/studyplan/top-interview-150/) + ## 📺 YouTube Playlist +- [AlgoMaster LeetCode Pattern Playlist](https://www.youtube.com/playlist?list=PLK63NuByH5o-tqaMUHRA4r8ObRW7PWz45) - [Abdul Bari's Algorithms Playlist](https://www.youtube.com/playlist?list=PLDN4rrl48XKpZkf03iYFl-O29szjTrs_O) - [William Fiset's Data Structure Playlist](https://www.youtube.com/playlist?list=PLDV1Zeh2NRsB6SWUrDFW2RmDotAfPbeHu) - [William Fiset's Graphs Playlist](https://www.youtube.com/playlist?list=PLDV1Zeh2NRsDGO4--qE8yH72HFL1Km93P) @@ -87,11 +94,8 @@ If you want to practice curated list of LeetCode problems organized by patterns, - [Data Structures And Algorithms Made Easy](https://amzn.to/40bsEUF) - [Cracking the Coding Interview](https://amzn.to/4e4HNdE) -## ✅ Curated Problems -- [AlgoMaster 300](https://algomaster.io/practice/dsa-patterns) -- [Blind 75](https://leetcode.com/discuss/general-discussion/460599/blind-75-leetcode-questions) -- [Leetcode Top 100 Liked](https://leetcode.com/studyplan/top-100-liked/) -- [Leetcode Top Interview 150](https://leetcode.com/studyplan/top-interview-150/) +## 📩 Newsletter +- [AlgoMaster Newsletter](https://blog.algomaster.io/) ## 🔎 Visualization - [VisuAlgo](https://visualgo.net/en) From 33287c903dfd8918ef4c68ba989924a2c9d9c87d Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Mon, 30 Dec 2024 22:36:45 +0530 Subject: [PATCH 54/66] update book links --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 78ca9c5..408522f 100644 --- a/README.md +++ b/README.md @@ -91,8 +91,8 @@ If you want to practice curated list of LeetCode problems organized by patterns, - [Coursera - Algorithms, Part 2](https://www.coursera.org/learn/algorithms-part2) ## 📚 Books -- [Data Structures And Algorithms Made Easy](https://amzn.to/40bsEUF) -- [Cracking the Coding Interview](https://amzn.to/4e4HNdE) +- [Data Structures And Algorithms Made Easy](https://www.amazon.in/dp/B08CMLS7LZ) +- [Cracking the Coding Interview](https://www.amazon.in/dp/0984782850) ## 📩 Newsletter - [AlgoMaster Newsletter](https://blog.algomaster.io/) From ecae4b3b59dd33aa10e6e0a8099757ec0490480a Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Tue, 31 Dec 2024 00:28:15 +0530 Subject: [PATCH 55/66] add reverse linked list code --- patterns/c#/ReverseList.cs | 23 +++++++++++++++++++++++ patterns/c++/ReverseList.cpp | 18 ++++++++++++++++++ patterns/go/reverse_list.go | 19 +++++++++++++++++++ patterns/java/ReverseLinkedList.java | 20 ++++++++++++++++++++ patterns/javascript/reverseList.js | 19 +++++++++++++++++++ patterns/python/reverse_list.py | 16 ++++++++++++++++ patterns/typescript/reverseList.ts | 22 ++++++++++++++++++++++ 7 files changed, 137 insertions(+) create mode 100644 patterns/c#/ReverseList.cs create mode 100644 patterns/c++/ReverseList.cpp create mode 100644 patterns/go/reverse_list.go create mode 100644 patterns/java/ReverseLinkedList.java create mode 100644 patterns/javascript/reverseList.js create mode 100644 patterns/python/reverse_list.py create mode 100644 patterns/typescript/reverseList.ts diff --git a/patterns/c#/ReverseList.cs b/patterns/c#/ReverseList.cs new file mode 100644 index 0000000..1dd3572 --- /dev/null +++ b/patterns/c#/ReverseList.cs @@ -0,0 +1,23 @@ +public class ListNode { + public int val; + public ListNode next; + public ListNode(int val = 0, ListNode next = null) { + this.val = val; + this.next = next; + } +} + +public class Solution { + public ListNode ReverseList(ListNode head) { + ListNode prev = null; + ListNode curr = head; + + while (curr != null) { + ListNode next = curr.next; + curr.next = prev; + prev = curr; + curr = next; + } + return prev; + } +} \ No newline at end of file diff --git a/patterns/c++/ReverseList.cpp b/patterns/c++/ReverseList.cpp new file mode 100644 index 0000000..1740054 --- /dev/null +++ b/patterns/c++/ReverseList.cpp @@ -0,0 +1,18 @@ +struct ListNode { + int val; + ListNode* next; + ListNode(int x) : val(x), next(nullptr) {} +}; + +ListNode* reverseList(ListNode* head) { + ListNode* prev = nullptr; + ListNode* curr = head; + + while (curr != nullptr) { + ListNode* next = curr->next; + curr->next = prev; + prev = curr; + curr = next; + } + return prev; +} \ No newline at end of file diff --git a/patterns/go/reverse_list.go b/patterns/go/reverse_list.go new file mode 100644 index 0000000..8cbcaed --- /dev/null +++ b/patterns/go/reverse_list.go @@ -0,0 +1,19 @@ +package main + +type ListNode struct { + Val int + Next *ListNode +} + +func reverseList(head *ListNode) *ListNode { + var prev *ListNode = nil + curr := head + + for curr != nil { + next := curr.Next + curr.Next = prev + prev = curr + curr = next + } + return prev +} diff --git a/patterns/java/ReverseLinkedList.java b/patterns/java/ReverseLinkedList.java new file mode 100644 index 0000000..3bd0843 --- /dev/null +++ b/patterns/java/ReverseLinkedList.java @@ -0,0 +1,20 @@ +package patterns.java; + +class ListNode { + int val; + ListNode next; +} + +public class ReverseLinkedList { + public ListNode reverseList(ListNode head) { + ListNode prev = null; // Previous node, initially null + ListNode curr = head; // Current node starts from the head + while (curr != null) { + ListNode next = curr.next; // Store next node + curr.next = prev; // Reverse the current node's pointer + prev = curr; // Move prev to current + curr = next; // Move curr to next + } + return prev; // New head of the reversed list + } +} diff --git a/patterns/javascript/reverseList.js b/patterns/javascript/reverseList.js new file mode 100644 index 0000000..317f50e --- /dev/null +++ b/patterns/javascript/reverseList.js @@ -0,0 +1,19 @@ +class ListNode { + constructor(val = 0, next = null) { + this.val = val; + this.next = next; + } +} + +function reverseList(head) { + let prev = null; + let curr = head; + + while (curr !== null) { + let next = curr.next; + curr.next = prev; + prev = curr; + curr = next; + } + return prev; +} \ No newline at end of file diff --git a/patterns/python/reverse_list.py b/patterns/python/reverse_list.py new file mode 100644 index 0000000..ec842b3 --- /dev/null +++ b/patterns/python/reverse_list.py @@ -0,0 +1,16 @@ +class ListNode: + def __init__(self, val=0, next=None): + self.val = val + self.next = next + +def reverse_list(head): + prev = None + curr = head + + while curr: + next_node = curr.next + curr.next = prev + prev = curr + curr = next_node + + return prev \ No newline at end of file diff --git a/patterns/typescript/reverseList.ts b/patterns/typescript/reverseList.ts new file mode 100644 index 0000000..d757f7e --- /dev/null +++ b/patterns/typescript/reverseList.ts @@ -0,0 +1,22 @@ +class ListNode { + val: number; + next: ListNode | null; + + constructor(val: number = 0, next: ListNode | null = null) { + this.val = val; + this.next = next; + } +} + +function reverseList(head: ListNode | null): ListNode | null { + let prev: ListNode | null = null; + let curr: ListNode | null = head; + + while (curr !== null) { + let next: ListNode | null = curr.next; + curr.next = prev; + prev = curr; + curr = next; + } + return prev; +} \ No newline at end of file From 3f41a4a5580627a16797583d1ea3e7bc05689a3a Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Tue, 31 Dec 2024 11:43:42 +0530 Subject: [PATCH 56/66] Update linked list in-place reversal pattern link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 408522f..23ffd54 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ If you want to practice curated list of LeetCode problems organized by patterns, - [Fast and Slow Pointers Pattern](https://www.youtube.com/watch?v=b139yf7Ik-E) - [Kadane's Algorithm](https://www.youtube.com/watch?v=NUWAXbSlsws) - [Two Pointers Pattern](https://blog.algomaster.io/p/69025a2e-b0d5-4705-8507-bba16c2691f1) -- [Linked List In-place Reversal Pattern](https://blog.algomaster.io/p/7dcce8e9-beee-4fef-8874-7aae025031b1) +- [Linked List In-place Reversal Pattern](https://www.youtube.com/watch?v=auoTGovuo9A) - [Sliding Window Pattern](https://blog.algomaster.io/p/f4412a17-7a3a-4d0b-8e39-9ea8f429bf7c) - [Monotonic Stack Pattern](https://blog.algomaster.io/p/5dabff21-11f4-470d-8e38-76ff07c63fdf) - [Overlapping Intervals Pattern](https://blog.algomaster.io/p/812e72f7-eced-4256-a4c1-00606ae50679) From 554f53e4cc2d59a8f508964a77e679b3cc9ed36e Mon Sep 17 00:00:00 2001 From: Arnab Das <93949960+Arnab7456@users.noreply.github.com> Date: Thu, 16 Jan 2025 13:55:17 +0530 Subject: [PATCH 57/66] Integer Overflow in Max Heap Comparator for K Closest Points to Origin The current implementation can potentially cause overflow when the distances are large. issue solve Id: #21 --- patterns/java/TopKElements.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/patterns/java/TopKElements.java b/patterns/java/TopKElements.java index c84c391..15946b1 100644 --- a/patterns/java/TopKElements.java +++ b/patterns/java/TopKElements.java @@ -126,7 +126,9 @@ private int getDistance(int[] point) { public int[][] kClosestPointsToOriginMaxHeapApproach(int[][] points, int k) { // Max heap with custom comparator to compare by distance - PriorityQueue maxHeap = new PriorityQueue<>((a, b) -> getDistance(b) - getDistance(a)); + PriorityQueue maxHeap = new PriorityQueue<>( + (a, b) -> Integer.compare(getDistance(b), getDistance(a)) + ); // Iterate through all points for (int[] point : points) { @@ -146,4 +148,4 @@ public int[][] kClosestPointsToOriginMaxHeapApproach(int[][] points, int k) { return result; } -} \ No newline at end of file +} From 4dbefcd302ef54861a0c3ac096a5fb5fb981d6be Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Wed, 22 Jan 2025 22:59:49 +0530 Subject: [PATCH 58/66] add start leetcode article --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 23ffd54..44ffba8 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ This repository contains awesome LeetCode resources to learn Data Structures and If you want to practice curated list of LeetCode problems organized by patterns, checkout [AlgoMaster.io](https://algomaster.io) ## 💡 Tips -- [How to Start LeetCode](https://www.youtube.com/watch?v=Nx4bvwU0DqE) +- [How to Start LeetCode](https://blog.algomaster.io/p/how-to-start-leetcode-in-2025) - [How I Mastered DSA](https://blog.algomaster.io/p/how-i-mastered-data-structures-and-algorithms) ## 📌 Fundamental Concepts From 9ba0ae38a7cb9293fc5c4bd66c06b00ef5680131 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Fri, 24 Jan 2025 19:09:55 +0530 Subject: [PATCH 59/66] add monotonic stack pattern --- patterns/c#/MonotonicStack.cs | 35 ++++++++++++++++++++ patterns/c++/KadaneAlgorithm.cpp | 19 +++++++++++ patterns/c++/MonotonicStack.cpp | 39 +++++++++++++++++++++++ patterns/go/monotonic_stack.go | 46 +++++++++++++++++++++++++++ patterns/java/MonotonicStack.java | 43 +++++++++++++++++++++++++ patterns/javascript/monotonicStack.js | 31 ++++++++++++++++++ patterns/python/monotonic_stack.py | 26 +++++++++++++++ patterns/typescript/monotonicStack.ts | 31 ++++++++++++++++++ 8 files changed, 270 insertions(+) create mode 100644 patterns/c#/MonotonicStack.cs create mode 100644 patterns/c++/MonotonicStack.cpp create mode 100644 patterns/go/monotonic_stack.go create mode 100644 patterns/java/MonotonicStack.java create mode 100644 patterns/javascript/monotonicStack.js create mode 100644 patterns/python/monotonic_stack.py create mode 100644 patterns/typescript/monotonicStack.ts diff --git a/patterns/c#/MonotonicStack.cs b/patterns/c#/MonotonicStack.cs new file mode 100644 index 0000000..2d1d89e --- /dev/null +++ b/patterns/c#/MonotonicStack.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; + +public class MonotonicStack { + public int[] NextGreaterElement(int[] nums) { + int n = nums.Length; + int[] result = new int[n]; + Array.Fill(result, -1); // Default to -1 if no greater element exists + Stack stack = new Stack(); // Stack stores indices + + for (int i = 0; i < n; i++) { + while (stack.Count > 0 && nums[i] > nums[stack.Peek()]) { + int index = stack.Pop(); + result[index] = nums[i]; + } + stack.Push(i); + } + return result; + } + + public int[] DailyTemperatures(int[] temperatures) { + int n = temperatures.Length; + int[] result = new int[n]; // Result array initialized with 0s + Stack stack = new Stack(); // Monotonic decreasing stack + + for (int i = 0; i < n; i++) { + while (stack.Count > 0 && temperatures[i] > temperatures[stack.Peek()]) { + int prevIndex = stack.Pop(); + result[prevIndex] = i - prevIndex; + } + stack.Push(i); + } + return result; + } +} \ No newline at end of file diff --git a/patterns/c++/KadaneAlgorithm.cpp b/patterns/c++/KadaneAlgorithm.cpp index e69de29..609f6ed 100644 --- a/patterns/c++/KadaneAlgorithm.cpp +++ b/patterns/c++/KadaneAlgorithm.cpp @@ -0,0 +1,19 @@ +#include +#include // For std::max + +class KadaneAlgorithm { +public: + int maxSubArray(std::vector& nums) { + int currentSum = nums[0]; // Start with the first element + int maxSum = nums[0]; // Initialize maxSum with the first element + + // Traverse the array from the second element + for (size_t i = 1; i < nums.size(); i++) { + // If currentSum is negative, reset to current element + currentSum = std::max(nums[i], currentSum + nums[i]); + // Update maxSum if currentSum is greater + maxSum = std::max(maxSum, currentSum); + } + return maxSum; + } +}; \ No newline at end of file diff --git a/patterns/c++/MonotonicStack.cpp b/patterns/c++/MonotonicStack.cpp new file mode 100644 index 0000000..e7ae2c8 --- /dev/null +++ b/patterns/c++/MonotonicStack.cpp @@ -0,0 +1,39 @@ +#include +#include + +using namespace std; + +class MonotonicStack { +public: + vector nextGreaterElement(vector& nums) { + int n = nums.size(); + vector result(n, -1); // Default to -1 if no greater element exists + stack stack; // Stack stores indices + + for (int i = 0; i < n; i++) { + while (!stack.empty() && nums[i] > nums[stack.top()]) { + int index = stack.top(); + stack.pop(); + result[index] = nums[i]; + } + stack.push(i); + } + return result; + } + + vector dailyTemperatures(vector& temperatures) { + int n = temperatures.size(); + vector result(n, 0); + stack stack; // Monotonic decreasing stack + + for (int i = 0; i < n; i++) { + while (!stack.empty() && temperatures[i] > temperatures[stack.top()]) { + int prevIndex = stack.top(); + stack.pop(); + result[prevIndex] = i - prevIndex; + } + stack.push(i); + } + return result; + } +}; \ No newline at end of file diff --git a/patterns/go/monotonic_stack.go b/patterns/go/monotonic_stack.go new file mode 100644 index 0000000..1f66f4b --- /dev/null +++ b/patterns/go/monotonic_stack.go @@ -0,0 +1,46 @@ +package main + +import "fmt" + +func nextGreaterElement(nums []int) []int { + n := len(nums) + result := make([]int, n) + for i := range result { + result[i] = -1 // Default to -1 if no greater element exists + } + stack := []int{} // Stack stores indices + + for i := 0; i < n; i++ { + for len(stack) > 0 && nums[i] > nums[stack[len(stack)-1]] { + index := stack[len(stack)-1] + stack = stack[:len(stack)-1] + result[index] = nums[i] + } + stack = append(stack, i) + } + return result +} + +func dailyTemperatures(temperatures []int) []int { + n := len(temperatures) + result := make([]int, n) // Result array initialized with 0s + stack := []int{} // Monotonic decreasing stack + + for i := 0; i < n; i++ { + for len(stack) > 0 && temperatures[i] > temperatures[stack[len(stack)-1]] { + prevIndex := stack[len(stack)-1] + stack = stack[:len(stack)-1] + result[prevIndex] = i - prevIndex + } + stack = append(stack, i) + } + return result +} + +func main() { + nums := []int{2, 1, 5, 6, 2, 3} + fmt.Println(nextGreaterElement(nums)) + + temperatures := []int{73, 74, 75, 71, 69, 72, 76, 73} + fmt.Println(dailyTemperatures(temperatures)) +} diff --git a/patterns/java/MonotonicStack.java b/patterns/java/MonotonicStack.java new file mode 100644 index 0000000..920b61f --- /dev/null +++ b/patterns/java/MonotonicStack.java @@ -0,0 +1,43 @@ +package patterns.java; + +import java.util.Arrays; +import java.util.Stack; + +public class MonotonicStack { + + public int[] nextGreaterElement(int[] nums) { + int n = nums.length; + int[] result = new int[n]; // Output array + Arrays.fill(result, -1); // Default to -1 if no greater element exists + Stack stack = new Stack<>(); // Stack stores indices + + // Iterate through the array + for (int i = 0; i < n; i++) { + // While stack is not empty and current element is greater than stack top + while (!stack.isEmpty() && nums[i] > nums[stack.peek()]) { + int index = stack.pop(); // Pop the top element + result[index] = nums[i]; // The current element is the Next Greater Element + } + stack.push(i); // Push the current index onto the stack + } + return result; + } + + public int[] dailyTemperatures(int[] temperatures) { + int n = temperatures.length; + int[] result = new int[n]; // Result array initialized with 0s + Stack stack = new Stack<>(); // Monotonic decreasing stack (stores indices) + + // Iterate through the temperature array + for (int i = 0; i < n; i++) { + // While stack is not empty AND the current temperature is warmer than the temperature at stack top + while (!stack.isEmpty() && temperatures[i] > temperatures[stack.peek()]) { + int prevIndex = stack.pop(); // Pop the previous day's index + result[prevIndex] = i - prevIndex; // Calculate the wait time + } + stack.push(i); // Push current index onto the stack + } + + return result; // Return the computed results + } +} \ No newline at end of file diff --git a/patterns/javascript/monotonicStack.js b/patterns/javascript/monotonicStack.js new file mode 100644 index 0000000..94918c4 --- /dev/null +++ b/patterns/javascript/monotonicStack.js @@ -0,0 +1,31 @@ +class MonotonicStack { + nextGreaterElement(nums) { + let n = nums.length; + let result = new Array(n).fill(-1); // Default to -1 if no greater element exists + let stack = []; // Stack stores indices + + for (let i = 0; i < n; i++) { + while (stack.length > 0 && nums[i] > nums[stack[stack.length - 1]]) { + let index = stack.pop(); + result[index] = nums[i]; + } + stack.push(i); + } + return result; + } + + dailyTemperatures(temperatures) { + let n = temperatures.length; + let result = new Array(n).fill(0); // Result array initialized with 0s + let stack = []; // Monotonic decreasing stack + + for (let i = 0; i < n; i++) { + while (stack.length > 0 && temperatures[i] > temperatures[stack[stack.length - 1]]) { + let prevIndex = stack.pop(); + result[prevIndex] = i - prevIndex; + } + stack.push(i); + } + return result; + } +} \ No newline at end of file diff --git a/patterns/python/monotonic_stack.py b/patterns/python/monotonic_stack.py new file mode 100644 index 0000000..62e51ce --- /dev/null +++ b/patterns/python/monotonic_stack.py @@ -0,0 +1,26 @@ +class MonotonicStack: + def next_greater_element(self, nums): + n = len(nums) + result = [-1] * n # Default to -1 if no greater element exists + stack = [] # Stack stores indices + + for i in range(n): + while stack and nums[i] > nums[stack[-1]]: + index = stack.pop() + result[index] = nums[i] + stack.append(i) + + return result + + def daily_temperatures(self, temperatures): + n = len(temperatures) + result = [0] * n # Result array initialized with 0s + stack = [] # Monotonic decreasing stack + + for i in range(n): + while stack and temperatures[i] > temperatures[stack[-1]]: + prev_index = stack.pop() + result[prev_index] = i - prev_index + stack.append(i) + + return result \ No newline at end of file diff --git a/patterns/typescript/monotonicStack.ts b/patterns/typescript/monotonicStack.ts new file mode 100644 index 0000000..a878002 --- /dev/null +++ b/patterns/typescript/monotonicStack.ts @@ -0,0 +1,31 @@ +class MonotonicStack { + nextGreaterElement(nums: number[]): number[] { + let n = nums.length; + let result: number[] = new Array(n).fill(-1); // Default to -1 if no greater element exists + let stack: number[] = []; // Stack stores indices + + for (let i = 0; i < n; i++) { + while (stack.length > 0 && nums[i] > nums[stack[stack.length - 1]]) { + let index = stack.pop()!; + result[index] = nums[i]; + } + stack.push(i); + } + return result; + } + + dailyTemperatures(temperatures: number[]): number[] { + let n = temperatures.length; + let result: number[] = new Array(n).fill(0); // Result array initialized with 0s + let stack: number[] = []; // Monotonic decreasing stack + + for (let i = 0; i < n; i++) { + while (stack.length > 0 && temperatures[i] > temperatures[stack[stack.length - 1]]) { + let prevIndex = stack.pop()!; + result[prevIndex] = i - prevIndex; + } + stack.push(i); + } + return result; + } +} \ No newline at end of file From 021e97d1daee2b52120143ec07efda48cad4c44f Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Fri, 24 Jan 2025 20:59:29 +0530 Subject: [PATCH 60/66] Add monotonic stack video --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 44ffba8..25590db 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ If you want to practice curated list of LeetCode problems organized by patterns, - [Two Pointers Pattern](https://blog.algomaster.io/p/69025a2e-b0d5-4705-8507-bba16c2691f1) - [Linked List In-place Reversal Pattern](https://www.youtube.com/watch?v=auoTGovuo9A) - [Sliding Window Pattern](https://blog.algomaster.io/p/f4412a17-7a3a-4d0b-8e39-9ea8f429bf7c) -- [Monotonic Stack Pattern](https://blog.algomaster.io/p/5dabff21-11f4-470d-8e38-76ff07c63fdf) +- [Monotonic Stack Pattern](https://www.youtube.com/watch?v=DtJVwbbicjQ) - [Overlapping Intervals Pattern](https://blog.algomaster.io/p/812e72f7-eced-4256-a4c1-00606ae50679) - [Backtracking Pattern](https://blog.algomaster.io/p/81d42ca2-600c-4252-aa33-a56462090048) - [Modified Binary Search Pattern](https://blog.algomaster.io/p/d0d81b04-4c2a-4b45-a101-5137c3146686) From 3bb0171f4a9499a7398bac9e87b882d9b8ae0c05 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Sat, 25 Jan 2025 18:29:22 +0530 Subject: [PATCH 61/66] add sliding window pattern --- patterns/c#/SlidingWindow.cs | 69 +++++++++++++++++++++ patterns/c++/SlidingWindow.cpp | 74 +++++++++++++++++++++++ patterns/go/sliding_window.go | 81 +++++++++++++++++++++++++ patterns/java/SlidingWindow.java | 90 ++++++++++++++++++++++++++++ patterns/javascript/slidingWindow.js | 62 +++++++++++++++++++ patterns/python/sliding_window.py | 46 ++++++++++++++ patterns/typescript/slidingWindow.ts | 62 +++++++++++++++++++ 7 files changed, 484 insertions(+) create mode 100644 patterns/c#/SlidingWindow.cs create mode 100644 patterns/c++/SlidingWindow.cpp create mode 100644 patterns/go/sliding_window.go create mode 100644 patterns/java/SlidingWindow.java create mode 100644 patterns/javascript/slidingWindow.js create mode 100644 patterns/python/sliding_window.py create mode 100644 patterns/typescript/slidingWindow.ts diff --git a/patterns/c#/SlidingWindow.cs b/patterns/c#/SlidingWindow.cs new file mode 100644 index 0000000..78fe833 --- /dev/null +++ b/patterns/c#/SlidingWindow.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; + +public class SlidingWindow { + public double FindMaxAverageBruteForce(int[] nums, int k) { + int n = nums.Length; + double maxAvg = double.MinValue; + + for (int i = 0; i <= n - k; i++) { + int sum = 0; + for (int j = i; j < i + k; j++) { + sum += nums[j]; + } + maxAvg = Math.Max(maxAvg, (double)sum / k); + } + return maxAvg; + } + + public double FindMaxAverageSlidingWindow(int[] nums, int k) { + int n = nums.Length; + int sum = 0; + + for (int i = 0; i < k; i++) { + sum += nums[i]; + } + + int maxSum = sum; + + for (int i = k; i < n; i++) { + sum += nums[i]; + sum -= nums[i - k]; + maxSum = Math.Max(maxSum, sum); + } + + return (double)maxSum / k; + } + + public int LengthOfLongestSubstringSlidingWindow(string s) { + HashSet seen = new HashSet(); + int maxLength = 0, left = 0; + + for (int right = 0; right < s.Length; right++) { + while (seen.Contains(s[right])) { + seen.Remove(s[left]); + left++; + } + seen.Add(s[right]); + maxLength = Math.Max(maxLength, right - left + 1); + } + return maxLength; + } + + public int LengthOfLongestSubstringSlidingWindowFrequencyArray(string s) { + int[] freq = new int[128]; + int maxLength = 0, left = 0; + + for (int right = 0; right < s.Length; right++) { + freq[s[right]]++; + + while (freq[s[right]] > 1) { + freq[s[left]]--; + left++; + } + + maxLength = Math.Max(maxLength, right - left + 1); + } + return maxLength; + } +} \ No newline at end of file diff --git a/patterns/c++/SlidingWindow.cpp b/patterns/c++/SlidingWindow.cpp new file mode 100644 index 0000000..6d12d0c --- /dev/null +++ b/patterns/c++/SlidingWindow.cpp @@ -0,0 +1,74 @@ +#include +#include +#include +#include + +using namespace std; + +class SlidingWindow { +public: + double findMaxAverageBruteForce(vector& nums, int k) { + int n = nums.size(); + double maxAvg = INT_MIN; + + for (int i = 0; i <= n - k; i++) { + int sum = 0; + for (int j = i; j < i + k; j++) { + sum += nums[j]; + } + maxAvg = max(maxAvg, (double)sum / k); + } + return maxAvg; + } + + double findMaxAverageSlidingWindow(vector& nums, int k) { + int n = nums.size(); + int sum = 0; + + for (int i = 0; i < k; i++) { + sum += nums[i]; + } + + int maxSum = sum; + + for (int i = k; i < n; i++) { + sum += nums[i]; + sum -= nums[i - k]; + maxSum = max(maxSum, sum); + } + + return (double)maxSum / k; + } + + int lengthOfLongestSubstringSlidingWindow(string s) { + unordered_set seen; + int maxLength = 0, left = 0; + + for (int right = 0; right < s.size(); right++) { + while (seen.count(s[right])) { + seen.erase(s[left]); + left++; + } + seen.insert(s[right]); + maxLength = max(maxLength, right - left + 1); + } + return maxLength; + } + + int lengthOfLongestSubstringSlidingWindowFrequencyArray(string s) { + vector freq(128, 0); + int maxLength = 0, left = 0; + + for (int right = 0; right < s.size(); right++) { + freq[s[right]]++; + + while (freq[s[right]] > 1) { + freq[s[left]]--; + left++; + } + + maxLength = max(maxLength, right - left + 1); + } + return maxLength; + } +}; \ No newline at end of file diff --git a/patterns/go/sliding_window.go b/patterns/go/sliding_window.go new file mode 100644 index 0000000..056b87d --- /dev/null +++ b/patterns/go/sliding_window.go @@ -0,0 +1,81 @@ +package main + +import ( + "math" +) + +// Brute Force Approach - O(n * k) +func findMaxAverageBruteForce(nums []int, k int) float64 { + n := len(nums) + maxAvg := math.Inf(-1) + + for i := 0; i <= n-k; i++ { + sum := 0 + for j := i; j < i+k; j++ { + sum += nums[j] + } + maxAvg = math.Max(maxAvg, float64(sum)/float64(k)) + } + return maxAvg +} + +// Sliding Window Approach - O(n) +func findMaxAverageSlidingWindow(nums []int, k int) float64 { + sum := 0 + for i := 0; i < k; i++ { + sum += nums[i] + } + + maxSum := sum + + for i := k; i < len(nums); i++ { + sum += nums[i] - nums[i-k] + if sum > maxSum { + maxSum = sum + } + } + + return float64(maxSum) / float64(k) +} + +// Sliding Window for Longest Substring Without Repeating Characters +func lengthOfLongestSubstringSlidingWindow(s string) int { + seen := make(map[byte]bool) + maxLength, left := 0, 0 + + for right := 0; right < len(s); right++ { + for seen[s[right]] { + delete(seen, s[left]) + left++ + } + seen[s[right]] = true + maxLength = max(maxLength, right-left+1) + } + return maxLength +} + +// Sliding Window using Frequency Array +func lengthOfLongestSubstringSlidingWindowFrequencyArray(s string) int { + freq := make([]int, 128) + maxLength, left := 0, 0 + + for right := 0; right < len(s); right++ { + freq[s[right]]++ + + for freq[s[right]] > 1 { + freq[s[left]]-- + left++ + } + + maxLength = max(maxLength, right-left+1) + } + return maxLength +} + +// Helper function to get max of two numbers +func max(a, b int) int { + if a > b { + return a + } + return b +} diff --git a/patterns/java/SlidingWindow.java b/patterns/java/SlidingWindow.java new file mode 100644 index 0000000..7fe3d79 --- /dev/null +++ b/patterns/java/SlidingWindow.java @@ -0,0 +1,90 @@ +package patterns.java; + +import java.util.HashSet; + +public class SlidingWindow { + public double findMaxAverageBruteForce(int[] nums, int k) { + int n = nums.length; + double maxAvg = Integer.MIN_VALUE; + + // Iterate through all possible subarrays of length k + for (int i = 0; i <= n - k; i++) { + int sum = 0; + + // Calculate sum of subarray starting at index i + for (int j = i; j < i + k; j++) { + sum += nums[j]; + } + + // Compute average and update maxAvg + maxAvg = Math.max(maxAvg, (double) sum / k); + } + return maxAvg; + } + + public double findMaxAverageSlidingWindow(int[] nums, int k) { + int n = nums.length; + + // Compute the sum of the first 'k' elements + int sum = 0; + for (int i = 0; i < k; i++) { + sum += nums[i]; + } + + // Initialize maxSum as the sum of the first window + int maxSum = sum; + + // Slide the window across the array + for (int i = k; i < n; i++) { + sum += nums[i]; // Add new element entering window + sum -= nums[i - k]; // Remove element leaving window + maxSum = Math.max(maxSum, sum); // Update maxSum + } + + // Return maximum average + return (double) maxSum / k; + } + + public int lengthOfLongestSubstringSlidingWindow(String s) { + int n = s.length(); + HashSet seen = new HashSet<>(); // Store characters in the current window + int maxLength = 0; + int left = 0; + + // Expand window by moving 'right' + for (int right = 0; right < n; right++) { + // If a duplicate is found, shrink the window from the left + while (seen.contains(s.charAt(right))) { + seen.remove(s.charAt(left)); + left++; + } + // Add current character to window and update max length + seen.add(s.charAt(right)); + maxLength = Math.max(maxLength, right - left + 1); + } + return maxLength; + } + + public int lengthOfLongestSubstringSlidingWindowFrequencyArray(String s) { + int n = s.length(); + int[] freq = new int[128]; // ASCII character frequency array + int maxLength = 0; + int left = 0; + + // Expand window by moving 'right' + for (int right = 0; right < n; right++) { + char currentChar = s.charAt(right); + freq[currentChar]++; // Increase frequency of the current character + + // If there is a duplicate, shrink the window from the left + while (freq[currentChar] > 1) { + freq[s.charAt(left)]--; // Remove character at left pointer + left++; // Shrink window + } + + // Update maximum window size + maxLength = Math.max(maxLength, right - left + 1); + } + return maxLength; + } +} \ No newline at end of file diff --git a/patterns/javascript/slidingWindow.js b/patterns/javascript/slidingWindow.js new file mode 100644 index 0000000..2e80ef0 --- /dev/null +++ b/patterns/javascript/slidingWindow.js @@ -0,0 +1,62 @@ +class SlidingWindow { + // Brute Force Approach - O(n * k) + findMaxAverageBruteForce(nums, k) { + let maxAvg = -Infinity; + + for (let i = 0; i <= nums.length - k; i++) { + let sum = 0; + for (let j = i; j < i + k; j++) { + sum += nums[j]; + } + maxAvg = Math.max(maxAvg, sum / k); + } + return maxAvg; + } + + // Sliding Window Approach - O(n) + findMaxAverageSlidingWindow(nums, k) { + let sum = nums.slice(0, k).reduce((a, b) => a + b, 0); + let maxSum = sum; + + for (let i = k; i < nums.length; i++) { + sum += nums[i] - nums[i - k]; + maxSum = Math.max(maxSum, sum); + } + + return maxSum / k; + } + + // Sliding Window for Longest Substring Without Repeating Characters + lengthOfLongestSubstringSlidingWindow(s) { + let seen = new Set(); + let maxLength = 0, left = 0; + + for (let right = 0; right < s.length; right++) { + while (seen.has(s[right])) { + seen.delete(s[left]); + left++; + } + seen.add(s[right]); + maxLength = Math.max(maxLength, right - left + 1); + } + return maxLength; + } + + // Sliding Window using Frequency Array + lengthOfLongestSubstringSlidingWindowFrequencyArray(s) { + let freq = new Array(128).fill(0); + let maxLength = 0, left = 0; + + for (let right = 0; right < s.length; right++) { + freq[s.charCodeAt(right)]++; + + while (freq[s.charCodeAt(right)] > 1) { + freq[s.charCodeAt(left)]--; + left++; + } + + maxLength = Math.max(maxLength, right - left + 1); + } + return maxLength; + } +} \ No newline at end of file diff --git a/patterns/python/sliding_window.py b/patterns/python/sliding_window.py new file mode 100644 index 0000000..b42e33d --- /dev/null +++ b/patterns/python/sliding_window.py @@ -0,0 +1,46 @@ +class SlidingWindow: + def find_max_average_brute_force(self, nums, k): + max_avg = float('-inf') + + for i in range(len(nums) - k + 1): + max_avg = max(max_avg, sum(nums[i:i + k]) / k) + + return max_avg + + def find_max_average_sliding_window(self, nums, k): + sum_window = sum(nums[:k]) + max_sum = sum_window + + for i in range(k, len(nums)): + sum_window += nums[i] - nums[i - k] + max_sum = max(max_sum, sum_window) + + return max_sum / k + + def length_of_longest_substring_sliding_window(self, s): + seen = set() + max_length = left = 0 + + for right in range(len(s)): + while s[right] in seen: + seen.remove(s[left]) + left += 1 + seen.add(s[right]) + max_length = max(max_length, right - left + 1) + + return max_length + + def length_of_longest_substring_sliding_window_frequency_array(self, s): + freq = [0] * 128 + max_length = left = 0 + + for right in range(len(s)): + freq[ord(s[right])] += 1 + + while freq[ord(s[right])] > 1: + freq[ord(s[left])] -= 1 + left += 1 + + max_length = max(max_length, right - left + 1) + + return max_length \ No newline at end of file diff --git a/patterns/typescript/slidingWindow.ts b/patterns/typescript/slidingWindow.ts new file mode 100644 index 0000000..86a2c8d --- /dev/null +++ b/patterns/typescript/slidingWindow.ts @@ -0,0 +1,62 @@ +class SlidingWindow { + // Brute Force Approach - O(n * k) + findMaxAverageBruteForce(nums: number[], k: number): number { + let maxAvg = -Infinity; + + for (let i = 0; i <= nums.length - k; i++) { + let sum = 0; + for (let j = i; j < i + k; j++) { + sum += nums[j]; + } + maxAvg = Math.max(maxAvg, sum / k); + } + return maxAvg; + } + + // Sliding Window Approach - O(n) + findMaxAverageSlidingWindow(nums: number[], k: number): number { + let sum = nums.slice(0, k).reduce((a, b) => a + b, 0); + let maxSum = sum; + + for (let i = k; i < nums.length; i++) { + sum += nums[i] - nums[i - k]; + maxSum = Math.max(maxSum, sum); + } + + return maxSum / k; + } + + // Sliding Window for Longest Substring Without Repeating Characters + lengthOfLongestSubstringSlidingWindow(s: string): number { + let seen = new Set(); + let maxLength = 0, left = 0; + + for (let right = 0; right < s.length; right++) { + while (seen.has(s[right])) { + seen.delete(s[left]); + left++; + } + seen.add(s[right]); + maxLength = Math.max(maxLength, right - left + 1); + } + return maxLength; + } + + // Sliding Window using Frequency Array + lengthOfLongestSubstringSlidingWindowFrequencyArray(s: string): number { + let freq = new Array(128).fill(0); + let maxLength = 0, left = 0; + + for (let right = 0; right < s.length; right++) { + freq[s.charCodeAt(right)]++; + + while (freq[s.charCodeAt(right)] > 1) { + freq[s.charCodeAt(left)]--; + left++; + } + + maxLength = Math.max(maxLength, right - left + 1); + } + return maxLength; + } +} \ No newline at end of file From 3f52ae5f01371a049e59531341acb6b721f6c3b1 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Sat, 25 Jan 2025 23:16:42 +0530 Subject: [PATCH 62/66] Update Sliding Window url --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 25590db..c38d716 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ If you want to practice curated list of LeetCode problems organized by patterns, - [Top 'K' Elements Pattern](https://www.youtube.com/watch?v=6_v6OoxvMOE) - [Fast and Slow Pointers Pattern](https://www.youtube.com/watch?v=b139yf7Ik-E) - [Kadane's Algorithm](https://www.youtube.com/watch?v=NUWAXbSlsws) +- [Sliding Window Pattern](https://www.youtube.com/watch?v=y2d0VHdvfdc) - [Two Pointers Pattern](https://blog.algomaster.io/p/69025a2e-b0d5-4705-8507-bba16c2691f1) - [Linked List In-place Reversal Pattern](https://www.youtube.com/watch?v=auoTGovuo9A) - [Sliding Window Pattern](https://blog.algomaster.io/p/f4412a17-7a3a-4d0b-8e39-9ea8f429bf7c) From aa1fbcc9d84aa1d772bbcbc19fc5ceeb10bb02a9 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Sun, 26 Jan 2025 19:22:53 +0530 Subject: [PATCH 63/66] add two pointers pattern --- patterns/c#/TwoPointers.cs | 59 +++++++++++++++++++++++++ patterns/c++/TwoPointers.cpp | 64 +++++++++++++++++++++++++++ patterns/go/two_pointers.go | 69 ++++++++++++++++++++++++++++++ patterns/java/TwoPointers.java | 59 +++++++++++++++++++++++++ patterns/javascript/twoPointers.js | 68 +++++++++++++++++++++++++++++ patterns/python/two_pointers.py | 48 +++++++++++++++++++++ patterns/typescript/twoPointers.ts | 57 ++++++++++++++++++++++++ 7 files changed, 424 insertions(+) create mode 100644 patterns/c#/TwoPointers.cs create mode 100644 patterns/c++/TwoPointers.cpp create mode 100644 patterns/go/two_pointers.go create mode 100644 patterns/java/TwoPointers.java create mode 100644 patterns/javascript/twoPointers.js create mode 100644 patterns/python/two_pointers.py create mode 100644 patterns/typescript/twoPointers.ts diff --git a/patterns/c#/TwoPointers.cs b/patterns/c#/TwoPointers.cs new file mode 100644 index 0000000..086b691 --- /dev/null +++ b/patterns/c#/TwoPointers.cs @@ -0,0 +1,59 @@ +using System; + +public class TwoPointers { + // Move Zeroes using Two Pointers + public void MoveZeroesTwoPointers(int[] nums) { + int left = 0; // Pointer for placing non-zero elements + + // Iterate with right pointer + for (int right = 0; right < nums.Length; right++) { + if (nums[right] != 0) { + // Swap elements if right pointer finds a non-zero + (nums[left], nums[right]) = (nums[right], nums[left]); + left++; // Move left pointer forward + } + } + } + + // Brute Force approach for Container with Most Water + public int MaxAreaBruteForce(int[] height) { + int n = height.Length; + int maxArea = 0; + + // Check all pairs (i, j) + for (int i = 0; i < n; i++) { + for (int j = i + 1; j < n; j++) { + // Compute the minimum height and width + int minHeight = Math.Min(height[i], height[j]); + int width = j - i; + int area = minHeight * width; // Compute water contained + + maxArea = Math.Max(maxArea, area); // Update max water + } + } + return maxArea; + } + + // Two Pointers approach for Container with Most Water + public int MaxAreaTwoPointers(int[] height) { + int left = 0, right = height.Length - 1; + int maxArea = 0; + + // Move pointers toward each other + while (left < right) { + int width = right - left; // Distance between lines + int minHeight = Math.Min(height[left], height[right]); // Compute height + int area = minHeight * width; // Compute water contained + + maxArea = Math.Max(maxArea, area); // Update max water + + // Move the pointer pointing to the shorter height + if (height[left] < height[right]) { + left++; // Move left pointer forward + } else { + right--; // Move right pointer backward + } + } + return maxArea; + } +} \ No newline at end of file diff --git a/patterns/c++/TwoPointers.cpp b/patterns/c++/TwoPointers.cpp new file mode 100644 index 0000000..8faea2b --- /dev/null +++ b/patterns/c++/TwoPointers.cpp @@ -0,0 +1,64 @@ +#include +#include +#include + +using namespace std; + +class TwoPointers { +public: + // Move Zeroes using Two Pointers + void moveZeroesTwoPointers(vector& nums) { + int left = 0; // Pointer for placing non-zero elements + + // Iterate with right pointer + for (int right = 0; right < nums.size(); right++) { + if (nums[right] != 0) { + // Swap elements if right pointer finds a non-zero + swap(nums[left], nums[right]); + left++; // Move left pointer forward + } + } + } + + // Brute Force approach for Container with Most Water + int maxAreaBruteForce(vector& height) { + int n = height.size(); + int maxArea = 0; + + // Check all pairs (i, j) + for (int i = 0; i < n; i++) { + for (int j = i + 1; j < n; j++) { + // Compute the minimum height and width + int minHeight = min(height[i], height[j]); + int width = j - i; + int area = minHeight * width; // Compute water contained + + maxArea = max(maxArea, area); // Update max water + } + } + return maxArea; + } + + // Two Pointers approach for Container with Most Water + int maxAreaTwoPointers(vector& height) { + int left = 0, right = height.size() - 1; + int maxArea = 0; + + // Move pointers toward each other + while (left < right) { + int width = right - left; // Distance between lines + int minHeight = min(height[left], height[right]); // Compute height + int area = minHeight * width; // Compute water contained + + maxArea = max(maxArea, area); // Update max water + + // Move the pointer pointing to the shorter height + if (height[left] < height[right]) { + left++; // Move left pointer forward + } else { + right--; // Move right pointer backward + } + } + return maxArea; + } +}; \ No newline at end of file diff --git a/patterns/go/two_pointers.go b/patterns/go/two_pointers.go new file mode 100644 index 0000000..1433c48 --- /dev/null +++ b/patterns/go/two_pointers.go @@ -0,0 +1,69 @@ +package main + +// Move Zeroes using Two Pointers +func moveZeroesTwoPointers(nums []int) { + left := 0 // Pointer for placing non-zero elements + + // Iterate with right pointer + for right := 0; right < len(nums); right++ { + if nums[right] != 0 { + // Swap elements if right pointer finds a non-zero + nums[left], nums[right] = nums[right], nums[left] + left++ // Move left pointer forward + } + } +} + +// Brute Force approach for Container with Most Water +func maxAreaBruteForce(height []int) int { + n := len(height) + maxArea := 0 + + // Check all pairs (i, j) + for i := 0; i < n; i++ { + for j := i + 1; j < n; j++ { + // Compute the minimum height and width + minHeight := min(height[i], height[j]) + width := j - i + area := minHeight * width // Compute water contained + + if area > maxArea { + maxArea = area // Update max water + } + } + } + return maxArea +} + +// Two Pointers approach for Container with Most Water +func maxAreaTwoPointers(height []int) int { + left, right := 0, len(height)-1 + maxArea := 0 + + // Move pointers toward each other + for left < right { + width := right - left // Distance between lines + minHeight := min(height[left], height[right]) // Compute height + area := minHeight * width // Compute water contained + + if area > maxArea { + maxArea = area // Update max water + } + + // Move the pointer pointing to the shorter height + if height[left] < height[right] { + left++ // Move left pointer forward + } else { + right-- // Move right pointer backward + } + } + return maxArea +} + +// Helper function to return the minimum of two integers +func min(a, b int) int { + if a < b { + return a + } + return b +} diff --git a/patterns/java/TwoPointers.java b/patterns/java/TwoPointers.java new file mode 100644 index 0000000..35cb395 --- /dev/null +++ b/patterns/java/TwoPointers.java @@ -0,0 +1,59 @@ +package patterns.java; + +public class TwoPointers { + + public void moveZeroesTwoPointers(int[] nums) { + int left = 0; // Pointer for placing non-zero elements + + // Iterate with right pointer + for (int right = 0; right < nums.length; right++) { + if (nums[right] != 0) { + // Swap elements if right pointer finds a non-zero + int temp = nums[left]; + nums[left] = nums[right]; + nums[right] = temp; + left++; // Move left pointer forward + } + } + } + + public int maxAreaBruteForce(int[] height) { + int n = height.length; + int maxArea = 0; + + // Check all pairs (i, j) + for (int i = 0; i < n; i++) { + for (int j = i + 1; j < n; j++) { + // Height of the container + int minHeight = Math.min(height[i], height[j]); + int width = j - i; // Distance between lines + int area = minHeight * width; // Compute water contained + + maxArea = Math.max(maxArea, area); // Update max water + } + } + return maxArea; + } + + public int maxAreaTwoPointers(int[] height) { + int left = 0, right = height.length - 1; + int maxArea = 0; + + // Move pointers toward each other + while (left <= right) { + int width = right - left; // Distance between lines + int minHeight = Math.min(height[left], height[right]); + int area = minHeight * width; // Compute water contained + + maxArea = Math.max(maxArea, area); // Update max water + + // Move the pointer pointing to the shorter height + if (height[left] < height[right]) { + left++; // Move left pointer forward + } else { + right--; // Move right pointer backward + } + } + return maxArea; + } +} \ No newline at end of file diff --git a/patterns/javascript/twoPointers.js b/patterns/javascript/twoPointers.js new file mode 100644 index 0000000..5c46a59 --- /dev/null +++ b/patterns/javascript/twoPointers.js @@ -0,0 +1,68 @@ +class TwoPointers { + /** + * Move Zeroes using Two Pointers + * @param {number[]} nums - Input array + */ + moveZeroesTwoPointers(nums) { + let left = 0; // Pointer for placing non-zero elements + + // Iterate with right pointer + for (let right = 0; right < nums.length; right++) { + if (nums[right] !== 0) { + // Swap elements if right pointer finds a non-zero + [nums[left], nums[right]] = [nums[right], nums[left]]; + left++; // Move left pointer forward + } + } + } + + /** + * Brute Force approach for Container with Most Water + * @param {number[]} height - Array of heights + * @return {number} - Maximum water that can be contained + */ + maxAreaBruteForce(height) { + let maxArea = 0; + let n = height.length; + + // Check all pairs (i, j) + for (let i = 0; i < n; i++) { + for (let j = i + 1; j < n; j++) { + // Compute the minimum height and width + let minHeight = Math.min(height[i], height[j]); + let width = j - i; + let area = minHeight * width; // Compute water contained + + maxArea = Math.max(maxArea, area); // Update max water + } + } + return maxArea; + } + + /** + * Two Pointers approach for Container with Most Water + * @param {number[]} height - Array of heights + * @return {number} - Maximum water that can be contained + */ + maxAreaTwoPointers(height) { + let left = 0, right = height.length - 1; + let maxArea = 0; + + // Move pointers toward each other + while (left < right) { + let width = right - left; // Distance between lines + let minHeight = Math.min(height[left], height[right]); // Compute height + let area = minHeight * width; // Compute water contained + + maxArea = Math.max(maxArea, area); // Update max water + + // Move the pointer pointing to the shorter height + if (height[left] < height[right]) { + left++; // Move left pointer forward + } else { + right--; // Move right pointer backward + } + } + return maxArea; + } +} \ No newline at end of file diff --git a/patterns/python/two_pointers.py b/patterns/python/two_pointers.py new file mode 100644 index 0000000..3e874f0 --- /dev/null +++ b/patterns/python/two_pointers.py @@ -0,0 +1,48 @@ +class TwoPointers: + # Move Zeroes using Two Pointers + def move_zeroes_two_pointers(self, nums): + left = 0 # Pointer for placing non-zero elements + + # Iterate with right pointer + for right in range(len(nums)): + if nums[right] != 0: + # Swap elements if right pointer finds a non-zero + nums[left], nums[right] = nums[right], nums[left] + left += 1 # Move left pointer forward + + # Brute Force approach for Container with Most Water + def max_area_brute_force(self, height): + n = len(height) + max_area = 0 + + # Check all pairs (i, j) + for i in range(n): + for j in range(i + 1, n): + # Compute the minimum height and width + min_height = min(height[i], height[j]) + width = j - i + area = min_height * width # Compute water contained + + max_area = max(max_area, area) # Update max water + return max_area + + # Two Pointers approach for Container with Most Water + def max_area_two_pointers(self, height): + left, right = 0, len(height) - 1 + max_area = 0 + + # Move pointers toward each other + while left < right: + width = right - left # Distance between lines + min_height = min(height[left], height[right]) # Compute height + area = min_height * width # Compute water contained + + max_area = max(max_area, area) # Update max water + + # Move the pointer pointing to the shorter height + if height[left] < height[right]: + left += 1 # Move left pointer forward + else: + right -= 1 # Move right pointer backward + + return max_area \ No newline at end of file diff --git a/patterns/typescript/twoPointers.ts b/patterns/typescript/twoPointers.ts new file mode 100644 index 0000000..8587625 --- /dev/null +++ b/patterns/typescript/twoPointers.ts @@ -0,0 +1,57 @@ +class TwoPointers { + // Move Zeroes using Two Pointers + moveZeroesTwoPointers(nums: number[]): void { + let left = 0; // Pointer for placing non-zero elements + + // Iterate with right pointer + for (let right = 0; right < nums.length; right++) { + if (nums[right] !== 0) { + // Swap elements if right pointer finds a non-zero + [nums[left], nums[right]] = [nums[right], nums[left]]; + left++; // Move left pointer forward + } + } + } + + // Brute Force approach for Container with Most Water + maxAreaBruteForce(height: number[]): number { + let maxArea = 0; + let n = height.length; + + // Check all pairs (i, j) + for (let i = 0; i < n; i++) { + for (let j = i + 1; j < n; j++) { + // Compute the minimum height and width + let minHeight = Math.min(height[i], height[j]); + let width = j - i; + let area = minHeight * width; // Compute water contained + + maxArea = Math.max(maxArea, area); // Update max water + } + } + return maxArea; + } + + // Two Pointers approach for Container with Most Water + maxAreaTwoPointers(height: number[]): number { + let left = 0, right = height.length - 1; + let maxArea = 0; + + // Move pointers toward each other + while (left < right) { + let width = right - left; // Distance between lines + let minHeight = Math.min(height[left], height[right]); // Compute height + let area = minHeight * width; // Compute water contained + + maxArea = Math.max(maxArea, area); // Update max water + + // Move the pointer pointing to the shorter height + if (height[left] < height[right]) { + left++; // Move left pointer forward + } else { + right--; // Move right pointer backward + } + } + return maxArea; + } +} \ No newline at end of file From c4a4f662ee6e41ae2be1c1c638e76152d6f3751e Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Sun, 26 Jan 2025 21:20:56 +0530 Subject: [PATCH 64/66] update two pointers links --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c38d716..8d2a4bb 100644 --- a/README.md +++ b/README.md @@ -42,14 +42,14 @@ If you want to practice curated list of LeetCode problems organized by patterns, ## 🚀 Patterns - [15 Leetcode Patterns](https://blog.algomaster.io/p/15-leetcode-patterns) - [20 DP Patterns](https://blog.algomaster.io/p/20-patterns-to-master-dynamic-programming) +- [Two Pointers Pattern](https://www.youtube.com/watch?v=QzZ7nmouLTI) +- [Sliding Window Pattern](https://blog.algomaster.io/p/f4412a17-7a3a-4d0b-8e39-9ea8f429bf7c) - [Prefix Sum Pattern](https://www.youtube.com/watch?v=yuws7YK0Yng) -- [Top 'K' Elements Pattern](https://www.youtube.com/watch?v=6_v6OoxvMOE) - [Fast and Slow Pointers Pattern](https://www.youtube.com/watch?v=b139yf7Ik-E) +- [Top 'K' Elements Pattern](https://www.youtube.com/watch?v=6_v6OoxvMOE) - [Kadane's Algorithm](https://www.youtube.com/watch?v=NUWAXbSlsws) - [Sliding Window Pattern](https://www.youtube.com/watch?v=y2d0VHdvfdc) -- [Two Pointers Pattern](https://blog.algomaster.io/p/69025a2e-b0d5-4705-8507-bba16c2691f1) - [Linked List In-place Reversal Pattern](https://www.youtube.com/watch?v=auoTGovuo9A) -- [Sliding Window Pattern](https://blog.algomaster.io/p/f4412a17-7a3a-4d0b-8e39-9ea8f429bf7c) - [Monotonic Stack Pattern](https://www.youtube.com/watch?v=DtJVwbbicjQ) - [Overlapping Intervals Pattern](https://blog.algomaster.io/p/812e72f7-eced-4256-a4c1-00606ae50679) - [Backtracking Pattern](https://blog.algomaster.io/p/81d42ca2-600c-4252-aa33-a56462090048) From ab5aff1809fedcf72a499a378eed916cdb11f259 Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Fri, 21 Feb 2025 18:11:01 +0530 Subject: [PATCH 65/66] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8d2a4bb..44bee45 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,9 @@ This repository contains awesome LeetCode resources to learn Data Structures and If you want to practice curated list of LeetCode problems organized by patterns, checkout [AlgoMaster.io](https://algomaster.io) ## 💡 Tips -- [How to Start LeetCode](https://blog.algomaster.io/p/how-to-start-leetcode-in-2025) - [How I Mastered DSA](https://blog.algomaster.io/p/how-i-mastered-data-structures-and-algorithms) +- [How to Start LeetCode](https://blog.algomaster.io/p/how-to-start-leetcode-in-2025) +- [15 Leetcode Patterns](https://blog.algomaster.io/p/15-leetcode-patterns) ## 📌 Fundamental Concepts - [Algorithmic Complexity](https://blog.algomaster.io/p/57bd4963-462f-4294-a972-4012691fc729) From a404f08093b9786c7af02f3ccc800d3dff219e6e Mon Sep 17 00:00:00 2001 From: Ashish Pratap Singh Date: Sat, 1 Mar 2025 02:39:27 +0530 Subject: [PATCH 66/66] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 44bee45..2ea2fc4 100644 --- a/README.md +++ b/README.md @@ -111,3 +111,9 @@ If you want to practice curated list of LeetCode problems organized by patterns, - [LeetCode VS Code Extension](https://marketplace.visualstudio.com/items?itemName=LeetCode.vscode-leetcode): Solve LeetCode problems in VS Code. Your contributions are most welcome! + +--- + +

+ If you find this resource helpful, please give it a star ⭐️ and share it with others! +